gcc中的C void指针计算

标签 c linux gcc

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

A missing cast means that when we are truncating a file which is less than 60 bytes, we don't trunate the wrong area of memory, and in fact we can end up truncating the next inode in the inode table, or worse yet, some other kernel data structure.

  • Addresses-Coverity-Id: #751987
  • Signed-off-by: "Theodore Ts'o"
  • Cc: 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 的 类型是__le32 的数组。 i_size 的类型是 long long。 我的问题是:老版本是按4字节计算,新版本是按1字节计算吗? 我的理解正确吗?

最佳答案

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

  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);
    

现在,很明显 p + i_size 的值将根据 p 的类型而有所不同,此补丁已修复。

关于gcc中的C void指针计算,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20980037/

相关文章:

c - 在 C 程序中给出意外的 sizeof union 输出

c++ - 相同代码中的不一致行为

c - 为什么这个程序只在第一次输入时给我一个错误计算?

C 警告 : incompatible pointer types passing

c - 如何在linux内核的memcpy函数中添加一个hook?

c - gcc 标准头文件中有这么多括号

linux - 如何使用 gcc/cmake 在 64 位 linux 机器上编译 32 位二进制文​​件

linux - 读取文件 "$"数据和 bash 脚本

linux - 缺少 Yarn-site.xml

c++ - webassembly 和 get_nprocs()