首页 > 科技 > 正文

LINUX 文件系统分析之VFS相关的概念及数据结构
2019-08-26 12:05:27   来源:东方头条   

针对linux内核而言,其基本上以“一切皆文件”的思想实现,linux内核针对字符设备、块设备、存储设备、网络通信的访问,都是注册成不同的文件系统(procfs、devtmpfs、ext3、ext4、ramdisk、sockfs、yaffs2、ubi、squashfs等),并实现具体的读写接口,最终由系统调用统一调用。而linux内核为了抽象文件系统的共性,便于对多文件系统的支持,向上次提供统一的接口,linux提供了vfs框架,本文主要介绍vfs框架相关的概念及相关的结构体。一、文件系统、vfs、系统调用之间的关系

而文件系统、vfs、系统调用之间的关系,如下图所示。

二、vfs相关的概念及结构体介绍

针对vfs主要涉及超级块(superblock)、目录项(dentry)、索引节点(inode)、文件系统类型。2.1 超级块(superblock)

superblock主要用于表示文件系统相关的信息,代表了一个文件系统整个信息,包括文件系统的类型、逻辑块大小、该文件系统支持的最大文件大小、根索引节点、根目录项、该文件系统类型、超级块相关的处理接口(索引节点相关的操作(节点的申请、释放、读、写)、获取文件系统的状态(statfs)、同步(sync_fs)等)

struct super_block {

struct list_head s_list; /*超级块相关的链接链表*/

dev_t s_dev; /* search index; _not_ kdev_t */

unsigned char s_blocksize_bits;/*块大小对应的bit位*/

unsigned long s_blocksize;/*块大小*/

loff_t s_maxbytes; /*该文件系统支持的最大文件字节数*/

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 */

#ifdef CONFIG_SMP

struct list_head __percpu *s_files;

#else

struct list_head s_files;/*指向struct files类型的指针变量*/

#endif

struct list_head s_mounts; /* list of mounts; _not_ for fs use */

/* s_dentry_lru, s_nr_dentry_unused protected by dcache.c lru locks */

struct list_head s_dentry_lru; /* unused dentry lru */

int s_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 */

int s_nr_inodes_unused; /* # of inodes on lru */

struct block_device *s_bdev;/*指向块设备类型的指针变量*/

struct backing_dev_info *s_bdi;

struct mtd_info *s_mtd;/*指向mtd相关的指针变量,这个与闪存设备抽象模块有关(内存技术模块)*/

struct hlist_node s_instances;

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;

};

如下为系统中超级块的链表

针对struct super_operations,主要是索引节点相关的操作接口、mount相关的接口等

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 *);

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

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);

};

2.2 目录项(dentry)

存放目录项与对应文件进行链接的信息,目录本身也是一个文件,当目录对应索引节点表示目录时,则索引节点(inode)中的块数据是该目录下所有文件或者子目录的名称;当目录对应索引节点表示文件时,则索引节点(inode)中的块数据中保存的是文件的数据。每一个目录或者文件均有一个索引节点(inode),该一个索引节点则可以和多个目录项关联。

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; /*指向到父dentry*/

struct qstr d_name;

struct inode *d_inode; /* 指向struct inode类型的指针,通过dentry与inode可以描述一个文件或目录*/

unsigned char d_iname[DNAME_INLINE_LEN]; /* small names */

/* Ref lookup also touches following */

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; /* 指向超级块*/

unsigned long d_time; /* used by d_revalidate */

void *d_fsdata; /* fs-specific data */

struct list_head d_lru; /* LRU list */

/*

* d_child and d_rcu can share memory

*/

union {

struct list_head d_child; /* child of parent list */

struct rcu_head d_rcu;

} d_u;

struct list_head d_subdirs; /* 该目录项的子项 */

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;

};

linux内核中文件系统变量之间的联系如下图所示

下面根据文件系统的注册函数,注册一个文件系统类型(该文件系统类型仅仅用于测试,未提供任何实质的内容),测试代码如下

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

static struct file_system_type test_fs_type = {

.name = "test-fs",

.kill_sb = kill_litter_super,

};

static int __init fs_test_init(void)

{

int err = register_filesystem(&test_fs_type);

if (err) {

printk(KERN_ERR "%s: unable to register devtmpfs type %i\n", __FUNCTION__, err);

return err;

}

return 0;

}

static void __exit fs_test_exit(void)

{

unregister_filesystem(&test_fs_type);

}

module_init(fs_test_init);

module_exit(fs_test_exit);

MODULE_LICENSE("GPL");

MODULE_DESCRIPTION("fs-test driver");

加载该驱动后,在/proc/filesystems下就存在新添加的文件系统类型了,如下图所示。

本章主要介绍vfs相关的概念以及数据结构,下一章继续进行文件系统注册及mount相关的内容介绍。

相关热词搜索:数据结构 系统分析 概念 文件 相关

上一篇:东芝开始研究5bit PLC闪存颗粒
下一篇:最后一页

济宁知名律师   电话:0531-80961678
手机:18053115917   微信:18053115917   QQ:709581498   邮箱:709581498@qq.com
网站地图 (XML地图 / 百度地图