引入:VFS
VFS(Virtual Filesystem Switch)称为虚拟文件系统或虚拟文件系统转换,是一个内核软件层,在具体的文件系统之上抽象的一层,用来处理与Posix文件系统相关的所有调用,给各种文件系统提供一个通用的接口,使上层的应用程序能够使用通用的接口访问不同文件系统,同时也为不同文件系统的通信提供了媒介。
VFS提供了一个抽象层,将POSIX API接口与不同存储设备的具体接口实现进行了分离,使得底层的文件系统类型、设备类型对上层应用程序透明。
linux下“一切皆文件”是Unix/Linux的基本哲学之一。unix标准文件:普通文件,目录文件,符号链接文件,设备文件,管道文件。
– 普通文件、d 目录文件、b 块设备、c 字符设备、l 符号链接文件、p 管道文件pipe、s 套接字文件socket
通用文件模型
数据类型 | Superblock | inode | dentry | file |
功能 | 存储文件系统元数据 | 文件相关的元数据 | 文件(目录)名称和具体的inode的对应关系,缓存最近最常访问的文件或目录,提示系统性能 | 进程与打开文件的交互 |
存储内容 | 文件系统类型、大小、状态(存放于磁盘文件系统控制块) | 文件的所有者(用户、组)、访问时间、文件类型等(存放于磁盘文件控制块) | 文件指针(文件当前位置) | |
是否存储在介质中 | 是 | 是 | 否 | 否 |
何时创建 | mount时从介质中读取,并常驻内存 | 文件打开时创建 | ||
内存中如何分配 | 名为filp的slab分配器高速缓存 | 名为dentry_cache的slab分配器高速缓存 | ||
重要成员 | s_list、 | |||
涉及操作函数 | *s_op | |||
维护 | 所有SB对象以双向循环链表链接在一起 | |||
是否缓存 | 是 |
Superblock
其成员相关信息在介质中存储,mount时读取介质信息并在内存中创建。
结构体定义
struct super_block {
struct list_head s_list; /* 支持挂载多个文件系统,并将super_block链起来 */
dev_t s_dev; /* search index; _not_ kdev_t */
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;
int s_count;
atomic_t s_active;
#ifdef CONFIG_SECURITY
void *s_security;
#endif
const struct xattr_handler **s_xattr;
struct list_head s_inodes; /* all inodes */
struct hlist_bl_head s_anon; /* anonymous dentries for (nfs) exporting */
struct list_head s_mounts; /* list of mounts; _not_ for fs use */
struct block_device *s_bdev;
struct backing_dev_info *s_bdi;
struct mtd_info *s_mtd;
struct hlist_node s_instances;
unsigned int s_quota_types; /* Bitmask of supported quota types */
struct quota_info s_dquot; /* Diskquota specific options */
struct sb_writers s_writers;
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;
/* AIO completions deferred from interrupt context */
struct workqueue_struct *s_dio_done_wq;
struct hlist_head s_pins;
/*
* Keep the lru lists last in the structure so they always sit on their
* own individual cachelines.
*/
struct list_lru s_dentry_lru ____cacheline_aligned_in_smp;
struct list_lru s_inode_lru ____cacheline_aligned_in_smp;
struct rcu_head rcu;
/*
* Indicates how deep in a filesystem stack this SB is
*/
int s_stack_depth;
};
重要成员
类型 | 类型名 | 成员名 | 作用 |
struct | list_head | s_list | 支持挂载多个文件系统,并将super_block链起来 |
struct | dentry | s_root | 该文件系统的根目录 |
struct | super_operations | *s_op | 文件系统相关操作函数 |
*s_d_op | |||
struct | file_system_type | *s_type | 文件系统类型名称,mount时指定类型名 |
void | *s_fs_info | 指向具体文件系统的超级块信息 | |
Index node(inode)
静态:创建文件系统时生成inode,保存在具体存储设备上,记录了文件系统的元信息;
动态:VFS在内存中使用inode数据结构,来管理文件系统的文件对象,记录了文件对象的详细信息,部分字段与关联的文件对象有关,会动态创建。
结构体定义
/*
* Keep mostly read-only and often accessed (especially for
* the RCU path lookup and 'stat' data) fields at the beginning
* of the 'struct inode'
*/
struct inode {
umode_t i_mode;
unsigned short i_opflags;
kuid_t i_uid;
kgid_t i_gid;
unsigned int i_flags;
#ifdef CONFIG_FS_POSIX_ACL
struct posix_acl *i_acl;
struct posix_acl *i_default_acl;
#endif
const struct inode_operations *i_op;
struct super_block *i_sb;
struct address_space *i_mapping;
#ifdef CONFIG_SECURITY
void *i_security;
#endif
/* Stat data, not accessed from path walking */
unsigned long i_ino;
/*
* Filesystems may only read i_nlink directly. They shall use the
* following functions for modification:
*
* (set|clear|inc|drop)_nlink
* inode_(inc|dec)_link_count
*/
union {
const unsigned int i_nlink;
unsigned int __i_nlink;
};
dev_t i_rdev;
loff_t i_size;
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;
unsigned int i_blkbits;
blkcnt_t i_blocks;
#ifdef __NEED_I_SIZE_ORDERED
seqcount_t i_size_seqcount;
#endif
/* Misc */
unsigned long i_state;
struct mutex i_mutex;
unsigned long dirtied_when; /* jiffies of first dirtying */
unsigned long dirtied_time_when;
struct hlist_node i_hash;
struct list_head i_wb_list; /* backing dev IO list */
struct list_head i_lru; /* inode LRU list */
struct list_head i_sb_list;
union {
struct hlist_head i_dentry;
struct rcu_head i_rcu;
};
u64 i_version;
atomic_t i_count;
atomic_t i_dio_count;
atomic_t i_writecount;
#ifdef CONFIG_IMA
atomic_t i_readcount; /* struct files open RO */
#endif
const struct file_operations *i_fop; /* former ->i_op->default_file_ops */
struct file_lock_context *i_flctx;
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;
#ifdef CONFIG_FSNOTIFY
__u32 i_fsnotify_mask; /* all events this inode cares about */
struct hlist_head i_fsnotify_marks;
#endif
void *i_private; /* fs or device private pointer */
};
重要成员
类型 | 类型名 | 成员名 | 作用 |
struct | inode_operations | *i_op | 索引节点操作函数列表 |
struct | super_block | *i_sb | 指向所属的超级块对象 |
long | \ | i_ino | 索引节点编号 |
short | \ | i_bytes | 最后一个块的有效字节数 |
int | i_blkbits | 每个块所占位数 | |
blkcnt_t | i_blocks | 文件所占块数 | |
Directory entry(dentry)
目录项=子目录项+文件
结构体定义
struct dentry {
/* RCU lookup touched fields */
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; /* Where the name belongs to - NULL is
* negative */
unsigned char d_iname[DNAME_INLINE_LEN]; /* small names */
/* Ref lookup also touches following */
struct lockref d_lockref; /* per-dentry lock and refcount */
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 */
struct list_head d_child; /* child of parent list */
struct list_head d_subdirs; /* our children */
/*
* d_alias and d_rcu can share memory
*/
union {
struct hlist_node d_alias; /* inode alias list */
struct rcu_head d_rcu;
} d_u;
};
重要成员
类型 | 类型名 | 成员名 | 作用 |
int | \ | d_flags | 标记,如是否为挂载点 |
d_hash | hash链表 | ||
struct | dentry | d_parent | 当前目录项的父目录项 |
unsigned char | d_iname | 文件名 | |
struct | qstr | d_name | 长文件名 |
d_inode | 与此dentry关联的文件inode | ||
struct | list_head | d_subdirs | 子目录项链表 |
struct | super_block | *d_sb | 所属文件系统超级块 |
File
结构体定义(include/linux/fs.h)
struct file {
union {
struct llist_node fu_llist;
struct rcu_head fu_rcuhead;
} f_u;
struct path f_path;
struct inode *f_inode; /* cached value */
const struct file_operations *f_op;
/*
* Protects f_ep_links, f_flags.
* Must not be taken from IRQ context.
*/
spinlock_t f_lock;
atomic_long_t f_count;
unsigned int f_flags;
fmode_t f_mode;
struct mutex f_pos_lock;
loff_t f_pos;
struct fown_struct f_owner;
const struct cred *f_cred;
struct file_ra_state f_ra;
u64 f_version;
#ifdef CONFIG_SECURITY
void *f_security;
#endif
/* 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;
struct list_head f_tfile_llink;
#endif /* #ifdef CONFIG_EPOLL */
struct address_space *f_mapping;
} __attribute__((aligned(4))); /* lest something weird decides that 2 is OK */
重要成员
类型 | 类型名 | 成员名 | 作用 |
文件系统类型
所有文件系统注册到file_systems单项链表中(register_filesystem()函数注册)。get_fs_type(name)获取file_system_type对象。
结构体定义
struct file_system_type {
const char *name;
int fs_flags;
#define FS_REQUIRES_DEV 1
#define FS_BINARY_MOUNTDATA 2
#define FS_HAS_SUBTYPE 4
#define FS_USERNS_MOUNT 8 /* Can be mounted by userns root */
#define FS_USERNS_DEV_MOUNT 16 /* A userns mount does not imply MNT_NODEV */
#define FS_USERNS_VISIBLE 32 /* FS must already be visible */
#define FS_RENAME_DOES_D_MOVE 32768 /* FS will handle d_move() during rename() internally. */
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 s_writers_key[SB_FREEZE_LEVELS];
struct lock_class_key i_lock_key;
struct lock_class_key i_mutex_key;
struct lock_class_key i_mutex_dir_key;
};
重要成员
类型 | 类型名 | 成员名 | 作用 |
char* | *name; | 文件系统名 | |
int | fs_flags | 文件系统类型标志 | |
dentry | mount | 文件系统挂在触发的操作 | |
kill_sb | 删除超级块 | ||
Linux 虚拟文件系统(VFS)介绍_落尘纷扰的博客-CSDN博客_虚拟文件系统
linux的VFS详解_土豆西瓜大芝麻的博客-CSDN博客_linux vfs