linux VFS数据结构(二)

目录项对象
存放目录项与对应文件进行链接的有关信息。每个磁盘文件系统都以自己特有的方式将该类信息存在磁盘上。
VFS把目录项当作目录文件来对待,路径中的每个组成部分有一个索引结点表示,虽然它们可以由索引结点表示,但VFS经常需要执行目录相关操作,比如路径的查找等。为了查找方便,VFS引入了目录项这个概念,每个目录项代表路径中一个特定部分。

01struct dentry {
02 atomic_t d_count;
03 unsigned int d_flags;  /* protected by d_lock */
04 spinlock_t d_lock;  /* per dentry lock */
05 int d_mounted;
06 struct inode *d_inode;  /* Where the name belongs to - NULL is
07      * negative */
08 /*
09  * The next three fields are touched by __d_lookup.  Place them here
10  * so they all fit in a cache line.
11  */
12 struct hlist_node d_hash; /* lookup hash list */
13 struct dentry *d_parent; /* parent directory */
14 struct qstr d_name;
15
16 struct list_head d_lru;  /* LRU list */
17 /*
18  * d_child and d_rcu can share memory
19  */
20 union {
21  struct list_head d_child; /* child of parent list */
22   struct rcu_head d_rcu;
23 } d_u;
24 struct list_head d_subdirs; /* our children */
25 struct list_head d_alias; /* inode alias list */
26 unsigned long d_time;  /* used by d_revalidate */
27 const struct dentry_operations *d_op;
28 struct super_block *d_sb; /* The root of the dentry tree */
29 void *d_fsdata;   /* fs-specific data */
30
31 unsigned char d_iname[DNAME_INLINE_LEN_MIN]; /* small names */
32};

第2行目录项对象引用计数器
第3行目录项高速缓存标志
第4行保护目录项对象的自旋锁
第6行与文件名关联的索引节点
第13行父目录的目录项对象
第14行文件名
第16行用于未使用目录项链表的指针
第21行对目录而言,用于同一父目录中的目录项链表的指针
第24行对目录而言,子目录项链表的头
第25行用于与同一索引节点相关的目录项链表的指针
第26行由d_revalidate方法使用
第27行目录项方法
第28行文件的超级块对象
第29行依赖于文件系统的数据
第31行存放短文件名的空间
每个目录项对象都有四种状态,只能处于下列状态中的一种
空闲状态
 处于该状态的目录对象不包括有效的信息,且还没有被VFS使用。
未使用状态
 处于该状态的目录项对象当前还没有被内核使用。
正使用状态
 处于该状态的目录项对象当前正在被内核使用。
负状态
 与目录项关联的索引节点不复存在,那是因为相应的磁盘索引节点被删除,或者因为目录项对象是通过解析一个不存在文件的路径名创建的。
目录项的操作方法

01struct dentry_operations {
02 int (*d_revalidate)(struct dentry *, struct nameidata *);
03 int (*d_hash) (struct dentry *, struct qstr *);
04 int (*d_compare) (struct dentry *, struct qstr *, struct qstr *);
05 int (*d_delete)(struct dentry *);
06 void (*d_release)(struct dentry *);
07 void (*d_iput)(struct dentry *, struct inode *);
08 char *(*d_dname)(struct dentry *, char *, int);
09};

第2行把目录项对象转制为一个文件路径名之前,判定该目录项对象是否仍然有效。
第3行生成一个散列值,这是用于目录项散列表的,特定于具体文件系统的散列函数
第4行比较两个文件名。
第5行当对目录项对象的最后一个引用被删除时,调用这个方法
第6行当要释放一个目录项对象是,调用这个方法
第7行当一个目录项对象变为”负状态”时,调用这个方法
文件对象
文件对象描述进程怎样与一个打开的文件进行交互。文件对象是在文件被打开时创建的。文件对象在磁盘上没有对应的映像。

01struct file {
02 /*
03  * fu_list becomes invalid after file_free is called and queued via
04  * fu_rcuhead for RCU freeing
05  */
06 union {
07  struct list_head fu_list;
08  struct rcu_head  fu_rcuhead;
09 } f_u;
10 struct path  f_path;
11#define f_dentry f_path.dentry
12#define f_vfsmnt f_path.mnt
13 const struct file_operations *f_op;
14 spinlock_t  f_lock;  /* f_ep_links, f_flags, no IRQ */
15 atomic_long_t  f_count;
16 unsigned int   f_flags;
17 fmode_t   f_mode;
18 loff_t   f_pos;
19 struct fown_struct f_owner;
20 const struct cred *f_cred;
21 struct file_ra_state f_ra;
22
23 u64   f_version;
24#ifdef CONFIG_SECURITY
25 void   *f_security;
26#endif
27 /* needed for tty driver, and maybe others */
28 void   *private_data;
29
30#ifdef CONFIG_EPOLL
31 /* Used by fs/eventpoll.c to link all the hooks to this file */
32 struct list_head f_ep_links;
33#endif /* #ifdef CONFIG_EPOLL */
34 struct address_space *f_mapping;
35#ifdef CONFIG_DEBUG_WRITECOUNT
36 unsigned long f_mnt_write_state;
37#endif
38};

第11行与文件相关的目录项对象
第12行含有文件的已安装文件系统
第13行指向文件操作表的指针
第15行文件对象的引用计数器
第16行当打开文件时所指定的标志
第17行进程的访问模式
第18行当前的文件位移量
第19行通过信号进行I/O事件通知的数据
第21行文件预读状态
第23行版本号
第25行指向文件对象的安全结构的指针
第28行指向特定系统或设备驱动程序所需要的数据的指针
第32行文件的事件轮询等待者链表的头
第34行指向文件地址空间对象的指针
文件的操作方法

01struct file_operations {
02 struct module *owner;
03 loff_t (*llseek) (struct file *, loff_t, int);
04 ssize_t (*read) (struct file *, char __user *, size_t, loff_t *);
05 ssize_t (*write) (struct file *, const char __user *, size_t, loff_t *);
06 ssize_t (*aio_read) (struct kiocb *, const struct iovec *, unsigned long, loff_t);
07 ssize_t (*aio_write) (struct kiocb *, const struct iovec *, unsigned long, loff_t);
08 int (*readdir) (struct file *, void *, filldir_t);
09 unsigned int (*poll) (struct file *, struct poll_table_struct *);
10 int (*ioctl) (struct inode *, struct file *, unsigned int, unsigned long);
11 long (*unlocked_ioctl) (struct file *, unsigned int, unsigned long);
12 long (*compat_ioctl) (struct file *, unsigned int, unsigned long);
13 int (*mmap) (struct file *, struct vm_area_struct *);
14 int (*open) (struct inode *, struct file *);
15 int (*flush) (struct file *, fl_owner_t id);
16 int (*release) (struct inode *, struct file *);
17 int (*fsync) (struct file *, struct dentry *, int datasync);
18 int (*aio_fsync) (struct kiocb *, int datasync);
19 int (*fasync) (int, struct file *, int);
20 int (*lock) (struct file *, int, struct file_lock *);
21 ssize_t (*sendpage) (struct file *, struct page *, int, size_t, loff_t *, int);
22 unsigned long (*get_unmapped_area)(struct file *, unsigned long, unsigned long, unsigned long, unsigned long);
23 int (*check_flags)(int);
24 int (*flock) (struct file *, int, struct file_lock *);
25 ssize_t (*splice_write)(struct pipe_inode_info *, struct file *, loff_t *, size_t, unsigned int);
26 ssize_t (*splice_read)(struct file *, loff_t *, struct pipe_inode_info *, size_t, unsigned int);
27 int (*setlease)(struct file *, long, struct file_lock **);
28};

第3行更新文件指针
第4行从文件的offset处读出count个字节
第5行从文件的offset处写入count个字节
第6行启动一个异步I/O操作。读数据
第7行启动一个异步I/O操作,写数据
第8行返回一个目录的下一个目录项。
第9行检查是否在一个文件上有操作发生,如果没有则睡眠,直到这个文件上有操作发生
第10行向一个基本硬件设备发送命令
第11行与ioctl方法类似,但它不用获得大内核锁
第12行64位的内核使用该方法执行32位的系统调用
第13行执行文件的内存映射,并将映射放入进程的地址空间
第14行通过创建一个新的文件而打开一个文件。
第15行当打开文件的引用被关闭时调用
第16行释放文件对象
第17行将文件所缓存的全部数据写入磁盘
第18行启动一次异步I/O刷新操作。
第19行通过信号来启用或禁止I/O事件通告
第20行对file文件申请一个锁
第23行当设置文件的状态标志时,fcntl()系统调用的服务例程调用这个方法执行附加的检查。
第24行用于定制flock()系统调用的行为。
每个注册的文件系统都用一个类型为file_system_type的对象来表示,该对象的字段如下。

01struct file_system_type {
02 const char *name;
03 int fs_flags;
04 int (*get_sb) (struct file_system_type *, int,
05         const char *, void *, struct vfsmount *);
06 void (*kill_sb) (struct super_block *);
07 struct module *owner;
08 struct file_system_type * next;
09 struct list_head fs_supers;
10
11 struct lock_class_key s_lock_key;
12 struct lock_class_key s_umount_key;
13
14 struct lock_class_key i_lock_key;
15 struct lock_class_key i_mutex_key;
16 struct lock_class_key i_mutex_dir_key;
17 struct lock_class_key i_alloc_sem_key;
18};

第2行文件系统名
第3行文件系统类型标志
第4行读超级块的方法
第6行删除超级块的方法
第7行指向实现文件系统的模块的指针
第8行指向文件系统类型链表中下一个元素的指针
第9行具有相同文件系统类型的超级块对象链表的头。
对于每个安装操作,内核必有在内存中保存安装点和安装标志,以及要安装文件系统与其它已安装文件系统之间的关系,这样的信息保存在已安装文件系统描述符中,这个描述符就是vfsmount类型的数据结构,其字段如下

01struct vfsmount {
02 struct list_head mnt_hash;
03 struct vfsmount *mnt_parent; /* fs we are mounted on */
04 struct dentry *mnt_mountpoint; /* dentry of mountpoint */
05 struct dentry *mnt_root; /* root of the mounted tree */
06 struct super_block *mnt_sb; /* pointer to superblock */
07 struct list_head mnt_mounts; /* list of children, anchored here */
08 struct list_head mnt_child; /* and going through their mnt_child */
09 int mnt_flags;
10 /* 4 bytes hole on 64bits arches */
11 const char *mnt_devname; /* Name of device e.g. /dev/dsk/hda1 */
12 struct list_head mnt_list;
13 struct list_head mnt_expire; /* link in fs-specific expiry list */
14 struct list_head mnt_share; /* circular list of shared mounts */
15 struct list_head mnt_slave_list;/* list of slave mounts */
16 struct list_head mnt_slave; /* slave list entry */
17 struct vfsmount *mnt_master; /* slave is on master->mnt_slave_list */
18 struct mnt_namespace *mnt_ns; /* containing namespace */
19 int mnt_id;   /* mount identifier */
20 int mnt_group_id;  /* peer group identifier */
21 /*
22  * We put mnt_count & mnt_expiry_mark at the end of struct vfsmount
23  * to let these frequently modified fields in a separate cache line
24  * (so that reads of mnt_flags wont ping-pong on SMP machines)
25  */
26 atomic_t mnt_count;
27 int mnt_expiry_mark;  /* true if marked for expiry */
28 int mnt_pinned;
29 int mnt_ghosts;
30 /*
31  * This value is not stable unless all of the mnt_writers[] spinlocks
32  * are held, and all mnt_writer[]s on this mount have 0 as their ->count
33  */
34 atomic_t __mnt_writers;
35};

第2行用于散列表链表的指针
第3行指向父文件系统。
第4行指向这个文件系统安装点目录的dentry
第5行指向这个文件系统根目录的dentry
第6行指向这个文件系统的超级块对象
第7行包含所有文件系统描述符链表的头
第8行用于已安装文件系统链表mnt_mounts的指针
第9行标志
第11行设备文件名
第13行如果文件系统标记为到期,那么就设置该标志为true

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值