Hanks.Wang - 专注于操作系统与移动安全研究,Linux-Kernel/SELinux/SEAndroid/TrustZone/Encription/MDM Mail - byhankswang@gmail.com
VFS核心数据结构
本文中参照的Linux Kernel版本为3.4.5
URL: https://www.kernel.org/pub/linux/kernel/v3.x/linux-3.4.5.tar.gz
阅读Linux文件系统源代码的重要性
Linux VFS通过抽象的手段对多种文件系统类型均有良好的支持,通过阅读VFS源码可以很好的学习使用C语言开发面向对象的大型项目;Linux系统中本身对物理设备抽象成文件的设计,通过阅读VFS源代码有助于深度理解设备管理和文件系统关系;Linux程序开发中大量的glibc API的实现都和VFS有一定的关系,通过阅读VFS源代码有助于理解和帮助用户态和内核态程序的开发;由于VFS在内核中的重要地位,通过阅读VFS源代码有助于理解内核中其他模块的实现。
VFS中比较重要的数据结构包括struct super_block, struct file_system_type, struct super_operations, struct dentry,struct inode, struct inode_operations, struct file, struct file_operations ;其中相关的基本数据结构请认真阅读linux源码文件include/linux/fs.h
图1 - linux文件系统体系结构
1.超级块结构体 super_block
struct super_block定义在include/linux/fs.h:1418
struct super_block {
struct list_heads_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_ts_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 longs_flags;
unsigned longs_magic;
struct dentry*s_root;
struct rw_semaphore s_umount;
struct mutex s_lock;
ints_count;
atomic_t s_active;
#ifdef CONFIG_SECURITY
void *s_security;
#endif
const struct xattr_handler ** s_xattr;
struct list_heads_inodes;/* all inodes */
struct hlist_bl_head s_anon;/* anonymous dentries for (nfs) exporting */
#ifdef CONFIG_SMP
struct list_head __percpu *s_files;
#else
struct list_heads_files;
#endif
struct list_heads_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_ts_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 longs_flags;
unsigned longs_magic;
struct dentry*s_root;
struct rw_semaphore s_umount;
struct mutex s_lock;
ints_count;
atomic_t s_active;
#ifdef CONFIG_SECURITY
void *s_security;
#endif
const struct xattr_handler ** s_xattr;
struct list_heads_inodes;/* all inodes */
struct hlist_bl_head s_anon;/* anonymous dentries for (nfs) exporting */
#ifdef CONFIG_SMP
struct list_head __percpu *s_files;
#else
struct list_heads_files;
#endif
struct list_heads_mounts; /* list of mounts; _not_ for fs use */
/* s_dentry_lru, s_nr_dentry_unused protected by dcache.c lru locks */
struct list_heads_dentry_lru;/* unused dentry lru */
ints_nr_dentry_unused;/* # of dentry on lru */
/* s_inode_lru_lock protects s_inode_lru and s_nr_inodes_unused */
spinlock_t s_inode_lru_lock ____cacheline_aligned_in_smp;
struct list_head s_inode_lru;/* unused inode lru */
ints_nr_inodes_unused;/* # of inodes on lru */
struct block_device* s_bdev;
struct backing_dev_info * s_bdi;
struct mtd_info* s_mtd;
struct hlist_node s_instances;
struct quota_info s_dquot;/* Diskquota specific options */
int s_frozen;
wait_queue_head_ts_wait_unfrozen;
char s_id[32];/* Informational name */
u8 s_uuid[16];/* UUID */
void * s_fs_info;/* Filesystem private info */
unsigned int s_max_links;
fmode_t s_mode;
/* Granularity of c/m/atime in ns.
Cannot be worse than a second */
u32 s_time_gran;
/*
* The next field is for VFS *only*. No filesystems have any business
* even looking at it. You had been warned.
*/
struct mutex s_vfs_rename_mutex;/* Kludge */
/*
* Filesystem subtype. If non-empty the filesystem type field
* in /proc/mounts will be "type.subtype"
*/
char *s_subtype;
/*
* Saved mount options for lazy filesystems using
* generic_show_options()
*/
char __rcu *s_options;
const struct dentry_operations *s_d_op; /* default d_op for dentries */
/*
* Saved pool identifier for cleancache (-1 means none)
*/
int cleancache_poolid;
struct shrinker s_shrink;/* per-sb shrinker handle */
/* Number of inodes with nlink == 0 but still referenced */
atomic_long_t s_remove_count;
/* Being remounted read-only */
int s_readonly_remount;
};
/* s_dentry_lru, s_nr_dentry_unused protected by dcache.c lru locks */
struct list_heads_dentry_lru;/* unused dentry lru */
ints_nr_dentry_unused;/* # of dentry on lru */
/* s_inode_lru_lock protects s_inode_lru and s_nr_inodes_unused */
spinlock_t s_inode_lru_lock ____cacheline_aligned_in_smp;
struct list_head s_inode_lru;/* unused inode lru */
ints_nr_inodes_unused;/* # of inodes on lru */
struct block_device* s_bdev;
struct backing_dev_info * s_bdi;
struct mtd_info* s_mtd;
struct hlist_node s_instances;
struct quota_info s_dquot;/* Diskquota specific options */
int s_frozen;
wait_queue_head_ts_wait_unfrozen;
char s_id[32];/* Informational name */
u8 s_uuid[16];/* UUID */
void * s_fs_info;/* Filesystem private info */
unsigned int s_max_links;
fmode_t s_mode;
/* Granularity of c/m/atime in ns.
Cannot be worse than a second */
u32 s_time_gran;
/*
* The next field is for VFS *only*. No filesystems have any business
* even looking at it. You had been warned.
*/
struct mutex s_vfs_rename_mutex;/* Kludge */
/*
* Filesystem subtype. If non-empty the filesystem type field
* in /proc/mounts will be "type.subtype"
*/
char *s_subtype;
/*
* Saved mount options for lazy filesystems using
* generic_show_options()
*/
char __rcu *s_options;
const struct dentry_operations *s_d_op; /* default d_op for dentries */
/*
* Saved pool identifier for cleancache (-1 means none)
*/
int cleancache_poolid;
struct shrinker s_shrink;/* per-sb shrinker handle */
/* Number of inodes with nlink == 0 but still referenced */
atomic_long_t s_remove_count;
/* Being remounted read-only */
int s_readonly_remount;
};
2. 文件系统类型 file_system_type
struct file_system_type定义在include/linux/fs.h:1835
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 hlist_head fs_supers;
struct lock_class_key s_lock_key;
struct lock_class_key s_umount_key;
struct lock_class_key s_vfs_rename_key;
struct lock_class_key i_lock_key;
struct lock_class_key i_mutex_key;
struct lock_class_key i_mutex_dir_key;
};
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 hlist_head fs_supers;
struct lock_class_key s_lock_key;
struct lock_class_key s_umount_key;
struct lock_class_key s_vfs_rename_key;
struct lock_class_key i_lock_key;
struct lock_class_key i_mutex_key;
struct lock_class_key i_mutex_dir_key;
};
3. 文件系统超级操作 super_operations
super_operations定义在include/linux/fs.h1864行
struct super_operations {
struct inode *(*alloc_inode)(struct super_block *sb);
void (*destroy_inode)(struct inode *);
void (*dirty_inode) (struct inode *, int flags);
int (*write_inode) (struct inode *, struct writeback_control *wbc);
int (*drop_inode) (struct inode *);
void (*evict_inode) (struct inode *);
void (*put_super) (struct super_block *);
void (*write_super) (struct super_block *);
int (*sync_fs)(struct super_block *sb, int wait);
int (*freeze_fs) (struct super_block *);
int (*unfreeze_fs) (struct super_block *);
int (*statfs) (struct dentry *, struct kstatfs *);
int (*remount_fs) (struct super_block *, int *, char *);
void (*umount_begin) (struct super_block *);
int (*show_options)(struct seq_file *, struct dentry *);
int (*show_devname)(struct seq_file *, struct dentry *);
int (*show_path)(struct seq_file *, struct dentry *);
int (*show_stats)(struct seq_file *, struct dentry *);
void (*destroy_inode)(struct inode *);
void (*dirty_inode) (struct inode *, int flags);
int (*write_inode) (struct inode *, struct writeback_control *wbc);
int (*drop_inode) (struct inode *);
void (*evict_inode) (struct inode *);
void (*put_super) (struct super_block *);
void (*write_super) (struct super_block *);
int (*sync_fs)(struct super_block *sb, int wait);
int (*freeze_fs) (struct super_block *);
int (*unfreeze_fs) (struct super_block *);
int (*statfs) (struct dentry *, struct kstatfs *);
int (*remount_fs) (struct super_block *, int *, char *);
void (*umount_begin) (struct super_block *);
int (*show_options)(struct seq_file *, struct dentry *);
int (*show_devname)(struct seq_file *, struct dentry *);
int (*show_path)(struct seq_file *, struct dentry *);
int (*show_stats)(struct seq_file *, struct dentry *);
#ifdef CONFIG_QUOTA
ssize_t (*quota_read)(struct super_block *, int, char *, size_t, loff_t);
ssize_t (*quota_write)(struct super_block *, int, const char *, size_t, loff_t);
#endif
ssize_t (*quota_read)(struct super_block *, int, char *, size_t, loff_t);
ssize_t (*quota_write)(struct super_block *, int, const char *, size_t, loff_t);
#endif
int (*bdev_try_to_free_page)(struct super_block*, struct page*, gfp_t);
int (*nr_cached_objects)(struct super_block *);
void (*free_cached_objects)(struct super_block *, int);
};
int (*nr_cached_objects)(struct super_block *);
void (*free_cached_objects)(struct super_block *, int);
};
相关的参考文献:
https://www.ibm.com/developerworks/cn/aix/library/au-speakingunix14/