static inline void ext4_ext_store_pblock(struct ext4_extent *ex,
ext4_fsblk_t pb)
{
ex->ee_start_lo = cpu_to_le32((unsigned long) (pb & 0xffffffff));
ex->ee_start_hi = cpu_to_le16((unsigned long) ((pb >> 31) >> 1) &
0xffff);
}
Run Code Online (Sandbox Code Playgroud)
这段代码来自linux内核.见最后一行.它确实pb >> 31然后>> 1这与pb相同>> 32为什么不这样做?
谢谢
编辑:谢谢大家.发送补丁到ext4 maillist
这两种方法并不完全相同,具体取决于底层数据类型.标准(C11,6.5.7按位移位运算符)指出:
如果右操作数的值为负或大于或等于提升的左操作数的宽度,则行为未定义.
因此,如果要将32位宽整数类型32位向右移位,则会导致未定义的行为.然而,将它移位31位然后另一位是明确定义的.
这个特殊点,虽然有人可能这样做的原因,在这个特殊情况下可能没有实际意义.鉴于你的类型是unsigned long long(保证64位宽度),(x >> 31) >> 1和之间应该没有区别x >> 32.
但是,如果某个平台实际上定义ext4_fsblk_t为32位类型(或者如果它是从允许32位类型(a)的早期实现中继承),那么您将发现自己不得不采用两阶段转换来保证定义的行为.
(a):在它之间有一个临时阶段ext3,ext4它允许ext3以其范围移动到48位,这是通往ext4其64位数据类型的一个垫脚石.在此之前,8TB是文件系统的实际限制.
这是可能的,虽然我还没有证实,这代码来自过渡宿醉,前基础数据类型广泛上升到64位.
将要使用的类型sector_t有条件地定义为u64或者unsigned long,这可以解释为什么代码首先存在.在将其定义为后者的情况下,可能需要两阶段的转变.
然而,鉴于ext4已经离开了这个临时阶段,我不确定是否需要进行两阶段转变.最好的办法是提出变更请求,看看它是否被开发人员击落:-)
| 归档时间: |
|
| 查看次数: |
243 次 |
| 最近记录: |