struct inode
Linux中一切皆文件,当我们在Linux中创建一个文件时,就会在相应的文件系统创建一个inode与之对应,文件实体和文件的inode是一一对应的,创建好一个inode会存在存储器中,第一次open就会将inode在内存中有一个备份,同一个文件被多次打开并不会产生多个inode,当所有被打开的文件都被close之后,inode在内存中的实例才会被释放。既然如此,当我们使用mknod(或其他方法)创建一个设备文件时,也会在文件系统中创建一个inode,这个inode和其他的inode一样,用来存储关于这个文件的静态信息(不变的信息),包括这个设备文件对应的设备号,文件的路径以及对应的驱动对象etc。inode作为VFS四大对象之一,在驱动开发中很少需要自己进行填充,更多的是在open()方法中进行查看并根据需要填充我们的file结构。
对于不同的文件类型,inode被填充的成员内容也会有所不同,以创建字符设备为例,我们知道,cdev_add其实是把一个字符驱动对象和一个(一组)设备号联系到一起。而创建设备文件,其实是把设备文件和设备号联系到一起。至此,这三者就被绑定在一起了。这样,内核就有能力创建一个struct inode实例了。
struct inode { umode_t i_mode; unsigned short i_opflags; kuid_t i_uid; kgid_t i_gid; unsigned int i_flags; ... union { const struct file_operations *i_fop; /* former ->i_op->default_file_ops */ void (*free_inode)(struct inode *); }; struct file_lock_context *i_flctx; struct address_space i_data; struct list_head i_devices; union { struct pipe_inode_info *i_pipe; struct cdev *i_cdev; char *i_link; unsigned i_dir_seq; }; ... void *i_private; /* fs or device private pointer */ }
特殊文件类型的union:pipe、cdev、link、dir_seq,i_cdev表示这个inode属于一个字符设备文件,创建字符设备文件的时候会把与之相关的设备号的驱动对象cdev拿来填充
i_fop:创建设备文件的时候,i_fop 填充的是def_chr_fops、def_blk_fops、pipefifo_fops之一,参见创建过程中调用的init_special_inode()
void init_special_inode(struct inode *inode, umode_t mode, dev_t rdev) { inode->i_mode = mode; if (S_ISCHR(mode)) { inode->i_fop = &def_chr_fops; inode->i_rdev = rdev; } else if (S_ISBLK(mode)) { inode->i_fop = &def_blk_fops; inode->i_rdev = rdev; } else if (S_ISFIFO(mode)) inode->i_fop = &pipefifo_fops; else if (S_ISSOCK(mode)) ; /* leave it no_open_fops */ else printk(KERN_DEBUG "init_special_inode: bogus i_mode (%o) for" " inode %s:%lu\n", mode, inode->i_sb->s_id, inode->i_ino); }
const struct file_operations def_chr_fops = { .open = chrdev_open, .llseek = noop_llseek, };
struct file
每一个进程维护一个打开文件描述符表。open()的过程其实就是根据传入的路径创建一个 file 并将其赋值到数组中,并返回其索引。
struct file { ... struct path f_path; struct inode *f_inode; /* cached value */ const struct file_operations *f_op; /* * Protects f_ep, f_flags. * Must not be taken from IRQ context. */ spinlock_t f_lock; enum rw_hint f_write_hint; atomic_long_t f_count; unsigned int f_flags; fmode_t f_mode; struct mutex f_pos_lock; loff_t f_pos; struct fown_struct f_owner; const struct cred *f_cred; struct file_ra_state f_ra; u64 f_version; #ifdef CONFIG_SECURITY void *f_security; #endif /* needed for tty driver, and maybe others */ void *private_data; ... }
f_path:存储的是open传入的路径,VFS就是根据这个路径逐层找到相应的inode
f_inode:存储的是找到的inode
f_op:存储的就是驱动提供的file_operations对象,这个对象应该在第一次open()的时候被填充,具体地,应用层的open通过层层搜索会调用inode.i_fops->open(),对于字符设备文件即chrdev_open()
标签:operations,文件,struct,open,mode,file,Linux,inode From: https://www.cnblogs.com/god-of-death/p/17277683.html