总体架构图
fs_struct
struct fs_struct {
atomic_t count; //共享这个表的进程个数
rwlock_t lock; //用于表中字段的读/写自旋锁
int umask; // 当打开文件设置文件权限时所使用的位掩码
struct dentry
*root, //根目录的目录项
*pwd, //当前工作目录的目录项
*altroot; //
struct vfsmount
*rootmnt, //根目录所安装的文件系统对象
*pwdmnt, // 当前工作目录所安装的文件系统对象
*altrootmnt; //模拟根目录的目录项(在 80x86 结构上始终为 NULL)
};
struct files_struct
#define NR_OPEN_DEFAULT BITS_PER_LONG
#define BITS_PER_LONG 32 /* asm-i386 */
struct files_struct {
atomic_t count;
// fdtable 就是 APUE第3章 所说的文件描述符表`,fdt初始值指向fdtab
struct fdtable *fdt;
struct fdtable fdtab;
spinlock_t file_lock ____cacheline_aligned_in_smp;
int next_fd;
struct embedded_fd_set close_on_exec_init;
struct embedded_fd_set open_fds_init;
// 存放struct file地址的数组, 当打开文件数量大于32时,需要构造更多该类型的数组
struct file * fd_array[NR_OPEN_DEFAULT];
};
struct fdtable
文件描述符表
struct fdtable {
unsigned int max_fds;
int max_fdset;
struct file ** fd; /* current fd array */
fd_set *close_on_exec; // FD_CLOEXEC标志
fd_set *open_fds; //当前打开的文件
struct rcu_head rcu;
struct files_struct *free_files;
struct fdtable *next;
};
struct file
文件对象
/*顺序打乱,突出重点*/
struct file {
/*
* fu_list becomes invalid after file_free is called and queued via fu_rcuhead for RCU freeing
*/
union {
struct list_head fu_list;
struct rcu_head fu_rcuhead;
} f_u; /* 用于通用文件对象链表的指针 */
struct dentry *f_dentry; /* 与文件相关的目录项对象 */
mode_t f_mode; /* 进程的访问模式 */
unsigned int f_flags; /* 当打开文件时所指定的标志 */
loff_t f_pos; /* 当前的文件位移量(文件指针) */
atomic_t f_count; /* 文件对象的引用计数器 */
struct vfsmount *f_vfsmnt; /* 含有该文件的已安装文件系统 */
const struct file_operations *f_op; /* 指向文件操作表的指针 */
struct fown_struct f_owner; /* 通过信号进行 I/O 事件通知的数据 */
unsigned int f_uid, f_gid; /* 用户的 UID、 GID */
struct file_ra_state f_ra; /* 文件预读状态 */
unsigned long f_version; /* 版本号,每次使用后自动递增 */
void *f_security; /* 指向文件对象的安全结构的指针 */
/* needed for tty driver, and maybe others 指向特定文件系统或设备驱动程序所需的数据的指针*/
void *private_data;
#ifdef CONFIG_EPOLL
/* Used by fs/eventpoll.c to link all the hooks to this file */
struct list_head f_ep_links; /* 文件的事件轮询等待者链表的头 */
spinlock_t f_ep_lock; /* 保护 f_ep_links 链表的自旋锁 */
#endif /* #ifdef CONFIG_EPOLL */
struct address_space *f_mapping; /* 指向文件地址空间对象的指针 */
};
struct dentry
每个目录看作由若干子目录和文件组成的一个普通文件。
然而目录项不同,一旦目录项被读入内存, VFS 就把它转换成基于dentry结构的一个目录项对象。
对于进程查找的路径名中的每个分量,内核都为其创建一个目录项对象;
struct dentry {
atomic_t d_count; /* 目录项对象引用计数器 */
unsigned int d_flags; /* 目录项高速缓存标志 */
spinlock_t d_lock; /* 保护目录项对象的自旋锁 */
struct inode *d_inode; /* 与文件名关联的索引节点*/
struct qstr d_name; /* 文件名 */
struct list_head d_subdirs; /* 对目录而言,子目录项链表的头 */
/* The next three fields are touched by __d_lookup. Place them here
* so they all fit in a cache line.
*/
struct hlist_node d_hash; /* 指向散列表表项链表的指针 */
struct dentry *d_parent; /* 父目录的目录项对象 */
struct list_head d_lru; /* 用于未使用目录项链表的指针 */
/*
* d_child and d_rcu can share memory
*/
union {
struct list_head d_child; /* 对目录而言,用于同一父目录中的目录项链表的指针 */
struct rcu_head d_rcu; /* 回收目录项对象时,由 RCU 描述符使用 */
} d_u;
struct list_head d_alias; /* 用于与同一索引节点(别名)相关的目录项链表的指针 */
unsigned long d_time; /* 由 d_revalidate 方法使用 */
struct dentry_operations *d_op; /* 目录项方法 */
struct super_block *d_sb; /* 文件的超级块对象 */
void *d_fsdata; /* 依赖于文件系统的数据 */
void *d_extra_attributes; /* TUX-specific data */
#ifdef CONFIG_PROFILING
struct dcookie_struct *d_cookie; /* cookie,指向内核配置文件使用的数据结构的指针*/
#endif
int d_mounted; /* 对目录而言,用于记录安装该目录项的文件系统数的计数器 */
unsigned char d_iname[DNAME_INLINE_LEN_MIN]; /* 存放短文件名的空间 */
};
struct node
struct inode {
struct hlist_node i_hash; /* 用于散列链表的指针 */
struct list_head i_list; /* 用于描述索引节点当前状态的链表的指针 */
struct list_head i_sb_list; /* 用于超级块的索引节点链表的指针 */
struct list_head i_dentry; /* 引用索引节点的目录项对象链表的头 */
unsigned long i_ino; /* 索引节点号 */
atomic_t i_count; /* 引用计数器 */
umode_t i_mode; /* 文件类型与访问权限 */
unsigned int i_nlink; /* 硬链接数目 */
loff_t i_size; /* 文件的字节数 */
uid_t i_uid; /* 所有者标识符 */
gid_t i_gid; /* 所有者组标识符 */
dev_t i_rdev; /* 实设备标识符 */
struct timespec i_atime; /* 上次访问文件的时间 */
struct timespec i_mtime; /* 上次写文件的时间 */
struct timespec i_ctime; /* 上次修改索引节点的时间 */
unsigned int i_blkbits; /* 块的位数 */
unsigned long i_version; /* 版本号(每次使用后自动递增) */
blkcnt_t i_blocks; /* 文件的块数 */
unsigned short i_bytes; /* 文件中最后一个块的字节数 */
spinlock_t i_lock; /* 保护索引节点一些字段的自旋锁: i_blocks, i_bytes, maybe i_size */
struct mutex i_mutex; /* 索引节点信号量 */
struct rw_semaphore i_alloc_sem; /* 在直接 I/O 文件操作中避免出现竞争条件的读/写信号量 */
struct inode_operations *i_op; /* 索引节点的操作 */
const struct file_operations *i_fop; /* 缺省文件操作: former->i_op->default_file_ops */
struct super_block *i_sb; /* 指向超级块对象的指针 */
struct file_lock *i_flock; /* 指向文件锁链表的指针 */
struct address_space *i_mapping; /* 指向缓存 address_space 对象的指针 */
struct address_space i_data; /* 嵌入在 inode 中的文件的 address_space 对象 */
#ifdef CONFIG_QUOTA
struct dquot *i_dquot[MAXQUOTAS]; /* 索引节点磁盘限额 */
#endif
struct list_head i_devices; /* 用于具体的字符或块设备索引节点链表的指针 */
union {
struct pipe_inode_info *i_pipe; /* 如果文件是一个管道则使用它 */
struct block_device *i_bdev; /* 指向块设备驱动程序的指针 */
struct cdev *i_cdev; /* 指向字符设备驱动程序的指针 */
};
int i_cindex; /* 拥有一组次设备号的设备文件的索引 */
__u32 i_generation; /* 索引节点版本号(由某些文件系统使用) */
#ifdef CONFIG_DNOTIFY
unsigned long i_dnotify_mask; /* 目录通知事件的位掩码 */
struct dnotify_struct *i_dnotify; /* 用于目录通知 */
#endif
#ifdef CONFIG_INOTIFY
struct list_head inotify_watches; /* watches on this inode */
struct mutex inotify_mutex; /* protects the watches list */
#endif
unsigned long i_state; /* 索引节点的状态标志 */
unsigned long dirtied_when; /* 索引节点的弄脏时间(以节拍为单位) */
unsigned int i_flags; /* 文件系统的安装标志 */
atomic_t i_writecount; /* 用于写进程的引用计数器 */
void *i_security; /* 指向索引节点安全结构的指针 */
void *i_private; /* 指向私有数据的指针 */
#ifdef __NEED_I_SIZE_ORDERED
seqcount_t i_size_seqcount;/* SMP 系统为 i_size 字段获取一致值时使用的顺序计数器 */
#endif
};
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。