总体架构图fs_structstructfs_struct{atomic_tcount;//共享这个表的进程数rwlock_tlock;//读/写表中字段的自旋锁intumask;//当打开文件时设置文件权限时使用的位掩码structdentry*root,//根目录的目录条目*pwd,//当前工作目录的目录条目*altroot;//structvfsmount*rootmnt,//由根目录安装文件系统对象*pwdmnt,//当前工作目录安装的文件系统对象*altrootmnt;//模拟根目录的目录条目(在80x86结构上始终为NULL)};structfiles_struct#defineNR_OPEN_DEFAULTBITS_PER_LONG#defineBITS_PER_LONG32/*asm-i386*/structfiles_struct{atomic_tcount;//fdtable是APUE第3章提到的文件描述符表,fdt的初始值指向fdtabstructfdtable*fdt;结构fdtablefdtab;spinlock_tfile_lock____cacheline_aligned_in_smp;intnext_fd;结构embedded_fd_setclose_on_exec_init;结构embedded_fd_setopen_fds_init;//存放struct文件地址数组,当打开文件数大于32时,需要构造更多该类型数组structfile*fd_array[NR_OPEN_DEFAULT];};structfdtable文件描述符表structfdtable{unsignedintmax_fds;intmax_fdset;结构文件**fd;/*当前fd数组*/fd_set*close_on_exec;//FD_CLOEXEC标志fd_set*open_fds;//当前打开的文件structrcu_headrcu;结构files_struct*free_files;structfdtable*next;};structfileFileobject/*打乱顺序,突出重点*/structfile{/**fu_list在file_free被调用并通过fu_rcuhead排队等待RCU释放后失效*/union{structlist_headfu_list;结构rcu_headfu_rcuhead;}f_u;/*使用指向通用文件对象列表的指针*/structdentry*f_dentry;/*与文件相关的目录条目对象*/mode_tf_mode;/*进程的访问模式*/unsignedintf_flags;/*打开文件时指定的标志*/loff_tf_pos;/*当前文件位移(文件指针)*/atomic_tf_count;/*文件对象的引用计数器*/structvfsmount*f_vfsmnt;/*包含文件的挂载文件系统*/conststructfile_operations*f_op;/*指向文件操作表的指针*/structfown_structf_owner;/*通过信号通知I/O事件的数据*/unsignedintf_uid,f_gid;/*用户的UID,GID*/structfile_ra_statef_ra;/*文件预读状态*/无符号长f_version;/*版本号,每次使用后自动递增*/void*f_security;/*指向文件对象安全结构的指针*//*tty驱动程序需要,也可能其他指向特定文件系统或设备驱动程序指向程序所需数据的指针*/void*private_data;#ifdefCONFIG_EPOLL/*由fs/eventpoll.c用来将所有挂钩链接到该文件*/structlist_headf_ep_links;/*文件头的事件轮询等待链表*/spinlock_tf_ep_lock;/*自旋锁保护f_ep_links链表*/#endif/*#ifdefCONFIG_EPOLL*/structaddress_space*f_mapping;/*指向文件地址空间对象的指针*/};每个目录的structdentry是由若干个子目录和文件组成的一个普通文件。但是,目录条目不同。一旦目录项被读入内存,VFS就会根据dentry结构将其转换为目录项对象。对于进程查找的路径名中的每个组件,内核为它创建一个目录条目对象;structdentry{atomic_td_count;/*目录条目对象引用计数器*/unsignedintd_flags;/*目录条目缓存标志*/spinlock_td_lock;/*自旋锁保护目录条目对象*/structinode*d_inode;/*与文件名关联的inode*/structqstrd_name;/*文件名*/structlist_headd_subdirs;/*fordirectory换句话说,子目录项链列表的头部*//*接下来的三个字段被__d_lookup触及。将它们放在这里*所以它们都适合缓存行。*/结构hlist_noded_hash;/*指向哈希表条目列表的指针*/structdentry*d_parent;/*父目录的目录项对象*/structlist_headd_lru;/*未使用目录条目列表的指针*//**d_child和d_rcu可以共享内存*/union{structlist_headd_child;/*对于目录,指向同一父目录中的目录条目列表的指针*/structrcu_headd_rcu;/*回收目录项对象时由RCU描述符使用*/}d_u;结构list_headd_alias;/*指向与相同索引节点(别名)相关的目录项链表的指针*/unsignedlongd_time;/*由d_revalidate方法使用*/structdentry_operations*d_op;/*目录入口方法*/structsuper_b锁定*d_sb;/*文件的超级块对象*/void*d_fsdata;/*数据依赖于文件系统*/void*d_extra_attributes;/*TUX特定数据*/#ifdefCONFIG_PROFILINGstructdcookie_struct*d_cookie;/*cookie,指向内核配置文件使用的数据结构的指针*/#endifintd_mounted;/*对于目录,用于记录目录项所在文件系统数量的计数器*/unsignedchard_iname[DNAME_INLINE_LEN_MIN];/*存储短文件名的空间*/};structnodestructinode{structhlist_nodei_hash;/*哈希链表指针*/structlist_headi_list;/*描述inode当前状态的链表指针*/structlist_headi_sb_list;/*指向超级块的inode列表的指针*/structlist_headi_dentry;/*引用inode列表对象列表的头部*/unsignedlongi_ino;/*索引节点号*/atomic_ti_count;/*引用计数器*/umode_ti_mode;/*文件类型和访问权限*/unsignedinti_nlink;/*硬链接数*/loff_ti_size;/*文件的字节数*/uid_ti_uid;/*所有者标识符*/gid_ti_gid;/*所有者组标识符*/dev_ti_rdev;/*真实设备标识符*/structtimespeci_atime;/*最后一次访问文件的时间*/structtimespeci_mtime;/*最后一次写入文件的时间*/structtimespeci_ctime;/*最后修改的索引节点时间*/unsignedinti_blkbits;/*块的位数*/unsignedlongi_version;/*版本号(每次使用后自动递增)*/blkcnt_ti_blocks;/*文件的块数*/unsignedshorti_bytes;/*文件中最后一个块的字节数*/spinlock_ti_lock;/*自旋锁保护inode的某些字段:i_blocks、i_bytes,也许是i_size*/structmutexi_mutex;/*索引节点信号量*/structrw_semaphorei_alloc_sem;/*读/写信号量以避免直接I/O文件操作中的竞争条件*/structinode_operations*i_op;/*inode操作*/conststructfile_operations*i_fop;/*默认文件操作:former->i_op->default_file_ops*/structsuper_block*i_sb;/*指向超级块对象的指针*/structfile_lock*i_flock;/*指向文件锁定列表的指针*/structaddress_space*i_mapping;/*指向缓存地址空间对象指针的指针*/structaddress_spacei_data;/*嵌入到inode中的文件的地址空间对象*/#ifdefCONFIG_QUOTAstructdquot*i_dquot[MAXQUOTAS];/*inode磁盘配额*/#endifstructlist_headi_devices;/*对于特定的指向字符或块设备inode链表的指针*/union{structpipe_inode_info*i_pipe;/*如果文件是管道则使用它*/structblock_device*i_bdev;/*指向块设备驱动程序的指针*/structcdev*i_cdev;/*指向字符设备驱动程序的指针*/};inti_cindex;/*带有一组次设备号的设备文件索引*/__u32i_generation;/*inode版本号(一些文件系统使用)*/#ifdefCONFIG_DNOTIFYunsignedlongi_dnotify_mask;/*目录通知事件的位掩码*/structdnotify_struct*i_dnotify;/*用于目录通知*/#endif#ifdefCONFIG_INOTIFYstructlist_headinotify_watches;/*监视这个inode*/structmutexinotify_mutex;/*保护监视列表*/#endifunsignedlongi_state;/*inode的状态标志*/unsignedlongdirty_when;/*index以滴答为单位的节点脏时间*/unsignedinti_flags;/*文件系统的挂载标志*/atomic_ti_writecount;/*写入过程的引用计数器*/void*i_security;/*指向inode安全性的指针指向结构的指针*/void*i_private;/*指向私有数据的指针*/#ifdef__NEED_I_SIZE_ORDEREDseqcount_ti_size_seqcount;/*SMP系统使用的序列计数器来获取i_size字段的一致值*/#endif};
