为什么这种对 file_operations 的取消引用会以这种方式发生?

Why does this dereference to file_operations happen this way?

我正在引用 this 文章,我对这里的这段代码感到困惑:

    /* get a copy of file_operations from inode */
    proc_fops = *proc_inode->i_fop;
    /* backup the file_operations */
    backup_proc_fops = proc_inode->i_fop;

file_operations 是一个结构(存储 vfs 函数),proc_inode 将指向 inode file_operations (i_fop)。为什么他会再次尊重这一点?为什么不使用与 backup_proc_fops 相同的代码?

对结构的引用:

因为 i_fop 是一个 指向 struct file_operations 的指针,如果你想 复制 它的结构正在指向,您需要取消引用它。

这个:

struct file_operations proc_fops;
proc_fops = *proc_inode->i_fop;

将复制 i_fop 指向的整个 struct file_operations。换句话说,它是从 i_fop 的字段初始化的整个结构。这与执行以下操作相同:

struct mystruct { /*...*/ };

struct mystruct *ptr;
struct mystruct copy;

ptr = malloc(sizeof *ptr);
// ...

copy = *ptr;

另一方面,这个:

backup_proc_fops = proc_inode->i_fop;

仅将 指针 复制到 struct file_operations,而不是其内容。这与执行以下操作相同(从上面的示例继续):

struct mystruct *another_ptr;
another_ptr = ptr;

在你引用的link中,这一切都是因为proc_fops会被修改然后用来替换原来的i_fop proc_inode 中的指针:

/* modify the copy with out evil function */
proc_fops.iterate_shared = rk_iterate_shared;
/* overwrite the proc entry's file_operations */
proc_inode->i_fop = &proc_fops;

backup_proc_fops只会保留原始指针,以便稍后在卸载模块时恢复:

/* get inode and restore file_operations */
proc_inode = p.dentry->d_inode;
proc_inode->i_fop = backup_proc_fops;

除了这一切,还可以这样做:

proc_inode->i_fop->iterate_shared = rk_iterate_shared;

但是会修改原始结构,使更改不可逆。