linux内核file_operations的赋值流程跟踪

本文详细探讨了Linux内核中file_operations结构体的赋值流程,特别是在文件系统挂载如ext4时的具体步骤。从mount系统调用开始,经过ext4_mount、mount_bdev和fill_super等函数,最终确定不同类型的文件(如普通文件、目录、特殊文件)的文件操作指针。重点分析了ext4_file_operations及其对不同文件类型的初始化,揭示了如何根据文件类型设置相应的file_operations,如ext4_iget函数中对inode的初始化。同时,也涉及到了特殊文件如字符设备的文件操作指针初始化过程。
摘要由CSDN通过智能技术生成

我们知道linux系统中文件有很多种,包括普通文件,目录文件,设备文件,管道文件,套接字文件等.文件在内核中用file结构体表示,file对象中有个重要成员 f_op指针,它指向file_operations,该结构体定义了一系列文件操作的函数指针集合,例如open,read,write,ioctl,mmap等.当对文件进行操作时,最终是调用对应的函数指针进行操作.

linux中支持很多种文件系统,每个文件系统使用之前都必须要先注册才能使用,文件系统类型用结构体file_system_type表示,注册文件系统使用register_filesystem(struct file_system_type * fs),它的作用是将文件系统类型添加到全局链表file_systems中.下面我以linux主流磁盘文件系统类型ext4的注册流程进行分析.


//下面是定义一个ext4文件系统类型

static struct file_system_type ext4_fs_type = {
.owner = THIS_MODULE,
.name = "ext4",
.mount = ext4_mount,
.kill_sb = kill_block_super,
.fs_flags = FS_REQUIRES_DEV,
};


在用户空间执行mount系统调用进行挂载文件系统时会调用ext4_mount(),基本流程为:do_mount()->do_new_mount()->do_kern_mount()->vfs_kern_mount()->mount_fs()->ext4_fs_type.mount()->ext4_mount(),感兴趣的读者请自行分析.

static struct dentry *ext4_mount(struct file_system_type *fs_type, int flags,
      const char *dev_name, void *data)
{
return mount_bdev(fs_type, flags, dev_name, data, ext4_fill_super);
}

mount_bdev函数原型声明如下:

struct dentry *mount_bdev(struct file_system_type *fs_type,
int flags, const char *dev_name, void *data,
int (*fill_super)(struct super_block *, void *, int)) {

}

注意上面函数mount_bdev的最后一个参数ext4_fill_super,它是一个函数指针,指向函数ext4_fill_super.

mount_bdev中会调用ext4_fill_super()函数,代码片段如下:

struct dentry *mount_bdev(struct file_system_type *fs_type,
int flags, const char *dev_name, void *data,
int (*fill_super)(struct super_block *, void *, int))
{

.........

s->s_flags = flags | MS_NOSEC;
s->s_mode = mode;
strlcpy(s->s_id, bdevname(bdev, b), sizeof(s->s_id));
sb_set_blocksize(s, block_size(bdev));
error = fill_super(s, data, flags & MS_SILENT ? 1 : 0);
if (error) {
deactivate_locked_super(s);
goto error;
}


s->s_flags |= MS_ACTIVE;
bdev->bd_super = s;

}

下面看ext4_fill_super的执行流程代码片段:

static int ext4_fill_super(struct super_block *sb, void *data, int silent) {

.....

/*
* The jbd2_journal_load will have done any necessary log recovery,
* so we can safely mount the rest of the filesystem now.
*/


root = ext4_iget(sb, EXT4_ROOT_INO);
if (IS_ERR(root)) {
ext

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值