C中的C void指针计算

时间:2014-01-07 19:23:22

标签: c linux gcc

今天我在ext4树中发现了一个Linux内核补丁。

  

缺少强制转换意味着当我们截断较少的文件时   超过60个字节,我们不会将错误的内存区域分开,事实上   我们最终可能会截断inode表中的下一个inode,或者更糟   还有一些其他内核数据结构。

     
      
  • 地址 - Coverity-Id:#751987
  •   
  • 签名:“Theodore Ts'o”
  •   
  • 抄送:stable@vger.kernel.org
  •   

 fs/ext4/inline.c | 8 +++++---
 1 file changed, 5 insertions(+), 3 deletions(-)

diff --git a/fs/ext4/inline.c b/fs/ext4/inline.c
index c417e52..ed29e72 100644
--- a/fs/ext4/inline.c
+++ b/fs/ext4/inline.c
@@ -1928,9 +1928,11 @@ void ext4_inline_data_truncate(struct inode *inode, int *has_inline)
                }

                /* Clear the content within i_blocks. */
-               if (i_size < EXT4_MIN_INLINE_DATA_SIZE)
-                       memset(ext4_raw_inode(&is.iloc)->i_block + i_size, 0,
-                                       EXT4_MIN_INLINE_DATA_SIZE - i_size);
+               if (i_size < EXT4_MIN_INLINE_DATA_SIZE) {
+                       void *p = (void *) ext4_raw_inode(&is.iloc)->i_block;
+                       memset(p + i_size, 0,
+                              EXT4_MIN_INLINE_DATA_SIZE - i_size);
+               }

                EXT4_I(inode)->i_inline_size = i_size <
                                        EXT4_MIN_INLINE_DATA_SIZE ?

请注意。 i_block's类型是__le32的数组。 i_size的类型很长。 我的问题是:旧版本是基于4个字节进行计算,新版本是基于1个字节进行计算吗? 我的理解是否正确?

1 个答案:

答案 0 :(得分:4)

所以,让我们采用原始代码,并使其类型对读者非常明确。如果我们这样做,那么我们将看到以下两段代码:

  1. 原始代码:

    __le32 *p = (void *) ext4_raw_inode(&is.iloc)->i_block;
    memset(p + i_size, 0, EXT4_MIN_INLINE_DATA_SIZE - i_size);
    
  2. 新代码:

    void *p = (void *) ext4_raw_inode(&is.iloc)->i_block;
    memset(p + i_size, 0, EXT4_MIN_INLINE_DATA_SIZE - i_size);
    
  3. 现在,很明显p + i_size的值会有所不同,具体取决于此修补程序修复的p的类型。