VFS采用的是面向对象的设计思想,使用一簇数据结构来代表通用文件对象。所有内核中的数据结构都使用C结构体实现。
1.superblock(超级块)对象
保存一个挂在的文件系统的相关信息(Stores information concerning a mounted filesystem. For disk-based filesystems, this object usually corresponds to a filesystem control block stored on disk.)
(1)超级块用来描述特定文件系统的信息。它存放在磁盘特定的扇区中 ,它在使用的时候将信息存在于内存中。
转载请尊重原创、保留相关链接本文来自多宝平台:http://www.mbodb.com
(2)当内核对一个文件系统进行初始化和注册时在内存为其分配一个超级块,这就是VFS超级块。即,VFS超级块是各种具体文件系统在安装时建立的,并在这些文件系统卸载时被自动删除 。
1.1 数据结构
(3)超级块对象由结构体 super_block来体现。VFS超级块的数据结构为 super_block在include/linux/fs.h中可以查看
struct super_block {
…….
};
我们先来看一个图,再来具体解释:
其中主要的数据成员和解释如下:
(1) s_list :所有的超级块形成一个双联表,s_list.prev和s_list.next分别指向与当前超级块相邻的前一个元素和后一个元素。
(2) s_lock :保护链表免受多处理器系统上的同时访问。
(3) s_fs_info: 字段指向具体文件系统的超级块。
例如:超级块对象指的是Ext2文件系统,该字段就指向ext2_sb_info数据结构。
(4) s_dirt :来表示该超级块是否是脏的,也就是说,磁盘上的数据是否必须要更新。
(5) 超级块对象是通过函数alloc_super()创建并初始化的。在文件系统安装时,内核会调用该函数以便从磁盘读取文件系统超级块,并且将其信息填充到内存中的超级块对象中 。
1.2操作定义
超级对象中最重要的就是s_op,每一种文件系统都应该有自己的super_operations操作实例。它指向超级块的操作函数表, 它由struct super_operations结构体来表示。
现在来看一下它的定义:它的定义在 include/linux/fs.h头文件中可以看到
1560struct super_operations {
1561 struct inode *(*alloc_inode)(struct super_block *sb);
1562 void (*destroy_inode)(struct inode *);
1563
1564 void (*dirty_inode) (struct inode *);
1565 int (*write_inode) (struct inode *, struct writeback_control *wbc);
1566 int (*drop_inode) (struct inode *);
1567 void (*evict_inode) (struct inode *);
1568 void (*put_super) (struct super_block *);
1569 void (*write_super) (struct super_block *);
1570 int (*sync_fs)(struct super_block *sb, int wait);
1571 int (*freeze_fs) (struct super_block *);
1572 int (*unfreeze_fs) (struct super_block *);
1573 int (*statfs) (struct dentry *, struct kstatfs *);
1574 int (*remount_fs) (struct super_block *, int *, char *);
1575 void (*umount_begin) (struct super_block *);
1576
1577 int (*show_options)(struct seq_file *, struct vfsmount *);
1578 int (*show_stats)(struct seq_file *, struct vfsmount *);
1579#ifdef CONFIG_QUOTA
1580 ssize_t (*quota_read)(struct super_block *, int, char *, size_t, loff_t);
1581 ssize_t (*quota_write)(struct super_block *, int, const char *, size_t, loff_t);
1582#endif
1583 int (*bdev_try_to_free_page)(struct super_block*, struct page*, gfp_t);
1584};
(1) 可以看到该结构体中的每一项都是一个指向超级块操作函数的指针,超级块操作函数执行文件系统和索引节点的底层操作。
(2)当文件系统需要对超级块执行操作时,要在超级块对象中寻找需要的操作方法。
例如:一个文件系统要写自己的超级块,需要调用:
sturct super_block * sb;
sb->s_op->write_super(sb);
sb是指向文件系统超级块的指针,沿着该指针进入超级块操作函数表,并从表中取得writ_super()函数,该函数执行写入超级块的实际操作。
说明:
尽管writ_super()方法来自超级块,但是在调用时,还是要把超级块作为参数传递给它。因为没有C++的this指针。
(3)具体操作说明
struct inode * alloc_inode(struct super_block * sb) :创建和初始化一个新的索引结点。
void destroy_inode(struct super_block *sb) :释放指定的索引结点 。
void dirty_inode(struct inode *inode) :VFS在索引节点被修改时会调用此函数。
void write_inode(struct inode *inode, struct writeback_control *wbc) 将指定的inode写回磁盘。
void drop_inode( struct inode * inode):删除索引节点