Linux 软raid函数 - - align_to_barrier_unit_end

函数功能:获取barrier bucket对齐之后的扇区长度。

源码调用:

c 复制代码
 good_sectors = align_to_barrier_unit_end(sector_nr, good_sectors);

其中good_sectors的值为128,也就是缺省同步chunk size 64K,kretprobe跟踪的结果来看,跟踪到的值为128?这个值是固定的? - - 不是。

函数原型:static sector_t align_to_barrier_unit_end(sector_t start_sector, sector_t sectors)

参数:

  • start_sector:操作的其实扇区号。
  • sectors:期望操作的扇区范围。

返回值:可操作扇区的范围。

c 复制代码
static sector_t align_to_barrier_unit_end(sector_t start_sector,
                                          sector_t sectors)
{
        sector_t len;

        WARN_ON(sectors == 0);
        /*
         * len is the number of sectors from start_sector to end of the
         * barrier unit which start_sector belongs to.
         */
    	/* len 是start_sector所属的屏障单元从start_sector到末端的扇区数。 */
            len = round_up(start_sector + 1, BARRIER_UNIT_SECTOR_SIZE) -
              start_sector;

        if (len > sectors)
                len = sectors;

        return len;
}

/*
 * This looks more complex than it should be. But we need to
 * get the type for the ~ right in round_down (it needs to be
 * as wide as the result!), and we want to evaluate the macro
 * arguments just once each.
 */
#define __round_mask(x, y) ((__typeof__(x))((y)-1))
#define round_up(x, y) ((((x)-1) | __round_mask(x, y))+1)
#define round_down(x, y) ((x) & ~__round_mask(x, y))

举个例子,假设要对齐的起始扇区号为7,BARRIER_UNIT_SECTOR_SIZE的值为1<<17。

A = __round_mask = (1<<17) - 1 = 0 1111 1111 1111 1111

B = x - 1 = 8 - 1 = 0111

(A | B = 0 1111 1111 1111 1111) + 1 = 1 0000 0000 0000 0000

所以此时,round_up的返回值依然为BARRIER_UNIT_SECTOR_SIZE。

那么如果当起始扇区号大于BARRIER_UNIT_SECTOR_SIZE会是怎么样呢?假设起始扇区号为x = 1 0000 0000 0000 0010

A = __round_mask = (1<<17) - 1 = 0 1111 1111 1111 1111

B = x - 1 = 1 0000 0000 0000 0001

(A | B = 1 1111 1111 1111 1111) + 1 = 10 0000 0000 0000 0000

所以此时,round_up的返回值为BARRIER_UNIT_SECTOR_SIZE << 1,就是1<<18,是BARRIER_UNIT_SECTOR_SIZE 的两倍。

所以round_up 宏的作用是返回给定数 x 向上舍入到最接近的 y 的倍数。

整明白round_up函数的能力之后,再看看align_to_barrier_unit_end这个函数。

c 复制代码
len = round_up(start_sector + 1, BARRIER_UNIT_SECTOR_SIZE) - start_sector;

len的值是取到最接近BARRIER_UNIT_SECTOR_SIZE整数倍的值,然后再减去扇区的起始扇区的值,len的值就是是start_sector所属的屏障单元从start_sector到bucket末端的扇区数。

c 复制代码
+---------+--------barrier bucket------------+------------+
|         |                                  |            |
|    start sector			    bucket_end - sectors     |
+---------+--------barrier bucket------------+------------+
c 复制代码
        if (len > sectors)
                len = sectors;
  • 如果len大于期望操作的扇区数,表示所有扇区区间落在barrier bucket范围内,直接返回期望操作的扇区数。
  • 如果len小于等于期望操作的扇区数,表示有一部分扇区超过barrier bucket范围,只能返回在bucket范围内的长度len,以保证不越界。
相关推荐
一方热衷.4 分钟前
在线安装对应版本NVIDIA驱动
linux·运维·服务器
独自归家的兔7 分钟前
ubuntu系统安装dbswitch教程 - 备份本地数据到远程服务器
linux·运维·ubuntu
ONE_SIX_MIX10 分钟前
ubuntu 24.04 用rdp连接,桌面黑屏问题,解决
linux·运维·ubuntu
龙飞0510 分钟前
Systemd -systemctl - journalctl 速查表:服务管理 + 日志排障
linux·运维·前端·chrome·systemctl·journalctl
*小海豚*11 分钟前
在linux服务器上DNS正常,但是java应用调用第三方解析域名报错
java·linux·服务器
June`11 分钟前
muduo项目排查错误+测试
linux·c++·github·muduo网络库
消失的旧时光-194328 分钟前
Linux 编辑器入门:nano 与 vim 的区别与选择指南
linux·运维·服务器
晓131338 分钟前
第七章 【C语言篇:文件】 文件全面解析
linux·c语言·开发语言
唐装鼠1 小时前
Linux 下 malloc 内存分配机制详解
linux·malloc
予枫的编程笔记1 小时前
【Linux入门篇】Linux运维必学:Vim核心操作详解,告别编辑器依赖
linux·人工智能·linux运维·vim操作教程·程序员工具·编辑器技巧·新手学vim