虚拟文件系统相关结构描述
一,文件系统类型,挂载点,VFS超级快,目录项,节点结构
每一种文件系统类型都描述为一个file_system_type结构。
struct file_system_type {
const char *name;
int fs_flags;
struct dentry *(*mount) (struct file_system_type *, int,
const char *, void *);
void (*kill_sb) (struct super_block *);
struct module *owner;
struct file_system_type * next;
struct list_head fs_supers;
......
};
Name://保存文件系统名
fs_flags://保存控制挂载方式的标志,比如只读装载、禁止setuid/setgid等
Mount://在内存中创建一个超级快结构,并为该文件系统分配一个根目录结构。
kill_sb://不需要某文件系统时执行清理工作。
Owner://文件系统以模块形式加载时owner才有意义,NULL表示文件系统已持久编译到内核中。
Next://文件系统注册时将其挂载到链表file_systems中。
fs_supers://同一类型文件系统可以被多次挂载,所以同一类型文件系统可以有多个超级快结构,这些超级快聚集在一个链表中,fs_supers就是对应的链表头。
每一个装载的文件系统都对应一个 vfsmount结构。
struct vfsmount {
struct list_head mnt_hash;
struct vfsmount *mnt_parent; /* fs we are mounted on */
struct dentry *mnt_mountpoint; /* dentry of mountpoint */
struct dentry *mnt_root; /* root of the mounted tree */
struct super_block *mnt_sb; /* pointer to superblock */
......
struct list_head mnt_mounts; /* list of children, anchored here */
struct list_head mnt_child; /* and going through their mnt_child */
int mnt_flags;
......
const char *mnt_devname; /* Name of device e.g. /dev/dsk/hda1 */
struct list_head mnt_list;
struct list_head mnt_expire; /* link in fs-specific expiry list */
struct list_head mnt_share; /* circular list of shared mounts */
struct list_head mnt_slave_list;/* list of slave mounts */
struct list_head mnt_slave; /* slave list entry */
struct vfsmount *mnt_master; /* slave is on master->mnt_slave_list */
struct mnt_namespace *mnt_ns; /* containing namespace */
int mnt_id; /* mount identifier */
int mnt_group_id; /* peer group identifier */
int mnt_expiry_mark; /* true if marked for expiry */
int mnt_pinned;
int mnt_ghosts;
};
mnt_hash:在fs/namespace.c中定义了一个散列表mount_hashtable, vfsmount 实例地址和其对应挂载点地址用来计算散列值。冲突元素以链表形式实现,mnt_hash就是链表元素。
mnt_mountpoint:是当前文件系统的装载点在其父目录中的dentry结 构。文件系统本身的相对根目录所对应的dentry保存在mnt_root。这两个dentry实例表示同一目录。
mnt_sb:指向该类文件系统本次挂载对应的超级快。
mnt_mounts:用于链接子文件系统。
mnt_child:用于链接到父文件系统的mnt_mounts中。
mnt_flags:控制文件系统的安装模式。如设置标志MNT_NODEV表 示文件系统是虚拟的,即没有物理后端设备。相关标志在fs.h中定义。
mnt_slave、mnt_slave_list、mnt_master:它们实现了从属装载,主装 载将所有从属装载保存在一个链表上,mnt_slave_list作为链表头,mnt_slave作为链表元素,所有从属装载都通过mnt_master指向其主装载。
mnt_share:所有共享装载都保存在一个循环链表中,mnt_share作为 链表元素。
mnt_expiry_mark:如果为true表示装载的文件系统已经不再使用, mnt_expire用作链表元素,将所有自动过期的装载保存在一个循环链表上。
文件系统的挂载都会创建一个对应的超级块,用以描述整个文件系统的信息。
struct super_block {
struct list_head s_list; /* Keep this first */
dev_t s_dev; /* search index; _not_ kdev_t */
unsigned char s_dirt;
unsigned char s_blocksize_bits;
unsigned long s_blocksize;
loff_t s_maxbytes; /* Max file size */
struct file_system_type *s_type;
const struct super_operations *s_op;
const struct dquot_operations *dq_op;
const struct quotactl_ops *s_qcop;
const struct export_operations *s_export_op;
unsigned long s_flags;
unsigned long s_magic;
struct dentry *s_root;
struct rw_semaphore s_umount;
struct mutex s_lock;
int s_count;
atomic_t s_active;
......
struct list_head s_inodes; /* all inodes */
......
struct list_head s_files;
......
struct block_device *s_bdev;
struct backing_dev_info *s_bdi;
struct mtd_info *s_mtd;
struct list_head s_instances;
struct quota_info s_dquot; /* Diskquota specific options */
......
void *s_fs_info; /* Filesystem private info */
u32 s_time_gran;
......
};
s_list:用于将超级块结构链接到全局链表super_blocks中去。
s_dev、s_bdev:指定了底层文件系统数据所在的块设备。前者是用了 内核内部的编号,后者是一个指向内存中的block_device结构的指针。
s_dirt:如果超级块被改变就将该字段置为1.
s_blocksize,s_blocksize_bits:前一个指定了文件系统块的长度,单 位为字节,后者是对前一个值取以2为底的对数。
s_type:指向该超级块对应的文件系统类型。
s_op:处理超级块的一些方法,由底层文件系统的代码提供。
dq_op:指向某个具体的文件系统,用于限额操作的函数集合。
s_qcop:限额控制方法。
s_export_op:导出方法,用于nfsd与文件系统的交互。
s_flags:登录标志。
s_magic:幻数,区别于其他文件系统的标志。
s_root:将超级块与全局根目录的dentry项关联起来。
s_count:超级块引用计数。
s_active:超级块活动引用计数。
s_inodes: 所有inode的链表。
s_files:所有打开文件的file结构链表。
s_bdev:指向对应的块设备。
s_bdi:对应设备所支持的一些信息。
s_mtd:如果所对应的是mtd设备,该字段指向设备的mtd_info结构。
s_instances:统一文件系统类型的所有超级块结构都链接到 file_system_type 的fs_supers成员上,s_instances就是对应的链表元素。
s_dquot:磁盘配额相关选项。
s_fs_info:指向文件系统实现的私有数据。
s_time_gran:指定了文件系统支持的各种时间戳的最大的可能粒度。
file_system_type描述了一种文件系统类型;vfsmount描述了文件系统一次挂载的相关信息;super_block表示文件系统被装载后,装载点和文件系统本身的一些信息。一类文件系统只能有一个file_system_type,如果该类文件系统被多次装载,则有多个vfsmount和对应的多个super_block。
VFS中每个文件、目录文件都由一个唯一的VFS inode表示,每个VFS inode中的信息都从实际的文件系统中得到。
struct inode {
umode_t i_mode;
unsigned short i_opflags;
uid_t i_uid;
gid_t i_gid;
......
const struct inode_operations *i_op;
struct super_block *i_sb;
struct address_space *i_mapping;
......
unsigned long i_ino;
union {
const unsigned int i_nlink;
unsigned int __i_nlink;
};
dev_t i_rdev;
struct timespec i_atime;
struct timespec i_mtime;
struct timespec i_ctime;
spinlock_t i_lock; /* i_blocks, i_bytes, maybe i_size */
unsigned short i_bytes;
blkcnt_t i_blocks;
loff_t i_size;
......
unsigned long dirtied_when; /* jiffies of first dirtying */
struct hlist_node i_hash;
......
struct list_head i_sb_list;
union {
struct list_head i_dentry;
struct rcu_head i_rcu;
};
atomic_t i_count;
unsigned int i_blkbits;
......
const struct file_operations *i_fop;
struct file_lock *i_flock;
struct address_space i_data;
......
struct list_head i_devices;
union {
struct pipe_inode_info *i_pipe;
struct block_device *i_bdev;
struct cdev *i_cdev;
};
__u32 i_generation;
......
void *i_private; /* fs or device private pointer */
};
i_mode:文件类型和访问权限。
i_uid、i_gid:与该文件相关的用户ID和组ID。
i_op、i_fop:前者负责管理结构性的操作和文件相关属性的操作;后 者用于操作文件中包含的数据。
i_sb:指向文件所属文件系统对应的超级块结构。
i_mapping:相关地址映射。
i_ino:索引节点号,唯一标识一个inode结构。
i_nlink:使用该inode的硬链接总数。
i_rdev:该inide表示设备文件时该字段存储该设备的设备号。
i_atime、i_mtime、i_ctime:分别存储了最后访问时间,最后修改时 间,最后修改inode的时间。
i_size、i_blocks:保存文件的长度,前者按字节计算后者按块计算, i_blkbits是i_size以2为底的对数。
dirtied_when:第一次被修改发生的时间,以jiffies计。
i_hash:存放inode的散列值。
i_sb_list:将该inode链入对应超级块的链表s_inodes中。
i_count:使用技术器,表明使用该inode的进程数。
i_data:设备地址映射。
i_devices:利用该成员作为链表元素,使得块设备或字符设备可以维 护一个inode结构的链表。
i_generation:索引节点版本号。
i_dentry:指向同一个inode的dentry结构通过d_alias链接对应inode 的i_dentry队列中。
结构dentry将文件系统的路径与节点inode联系起来,通过文件系统路径可查找生成dentry结构,dentry结构生成后,通过文件的路径的hash值可直接查找到对应的dentry,进而找到对应的iniode结构。
struct dentry {
unsigned int d_flags; /* protected by d_lock */
seqcount_t d_seq; /* per dentry seqlock */
struct hlist_bl_node d_hash; /* lookup hash list */
struct dentry *d_parent; /* parent directory */
struct qstr d_name;
struct inode *d_inode; /* belongs to - NULL is * negative */
unsigned char d_iname[DNAME_INLINE_LEN]; /* small names */
unsigned int d_count; /* protected by d_lock */
spinlock_t d_lock; /* per dentry lock */
const struct dentry_operations *d_op;
struct super_block *d_sb; /* The root of the dentry tree */
unsigned long d_time; /* used by d_revalidate */
void *d_fsdata; /* fs-specific data */
struct list_head d_lru; /* LRU list */
union {
struct list_head d_child; /* child of parent list */
struct rcu_head d_rcu;
} d_u;
struct list_head d_subdirs; /* our children */
struct list_head d_alias; /* inode alias list */
};
d_flags:包含几个标志,比如DCACHE_DISCONNECTED表示dentry 没有连接到超级块的dentry树,DCACHE_UNHASHED表示该结构没有在任何inode的散列表中。
d_hash:内存中所有活动的dentry实例都保存在一个散列表中,该散 列表使用fs/dcache.c中的全局变量dentry_hashtable实现。
用d_hash实现溢出链,用于解决散列碰撞。
d_parent:指向父目录的dentry实例。
d_name:包含了dentry的名称,名称长度和hash值。
d_inode:指向相关inode实例的指针,如果为NULL表示该dentry 为一个不存在的文件名建立的。
d_iname:如果文件名只由少量字符组成,则保存在d_iname中。
d_count:内核中有一个全局链表dentry_unused,当d_count为0的目 录项结构都自动放置到该链表上。
d_op:指向一个函数集,提供对dentry对象的各种操作,这些操作有 底层文件系统实现。
d_sb:指向dentry所属文件系统的超级块实例。
d_fsdata:特定于文件系统的数据。
d_lru:共享计数为0的dentry结构都通过队列头d_lru链入LRU队 列dentry_unused在队列中等待释放或重新被使用。
d_child:用于链接到父目录的d_subdirs中的链表元素。
d_alias:指向同一个inode的dentry结构通过d_alias链接在一起。都 在该inode的i_dentry队列中。