文件系统设计之数据结构

一、实验

查看变量 super_blocks、sb_lock 的地址:

在这里插入图片描述

对代码进行修改,super_block.c 代码如下:

#include<linux/module.h>
#include<linux/fs.h>
#include<linux/init.h>
#include<linux/list.h>
#include<linux/spinlock.h>
#include<linux/kdev_t.h>

#define SUPER_BLOCKS_ADDRESS 0xffffffff940ff2b0
#define SB_LOCK_ADDRESS 0xffffffff9470ee98

static int __init my_init(void)
{
    struct super_block *sb;
    struct list_head *pos;
    struct list_head *linode;
    struct inode *pinode;
    unsigned long long count = 0;
    
    printk("\nPrint some fields of super_blocks:\n");
    spin_lock((spinlock_t *)SB_LOCK_ADDRESS);	//加锁
    list_for_each(pos, (struct list_head *)SUPER_BLOCKS_ADDRESS) {
        sb = list_entry(pos, struct super_block, s_list);
        printk("dev_t: %d : %d", MAJOR(sb->s_dev), MINOR(sb->s_dev));	//打印文件系统所在设备的主设备号和次设备号
        printk("  file_type name: %s\n",sb->s_type->name);		//打印文件系统名

        list_for_each(linode, &sb->s_inodes) {
            pinode=list_entry(linode,struct inode,i_sb_list);
            count++;
            printk(" %lu\t",pinode->i_ino);		//打印索引节点号
        }
    }
    spin_unlock((spinlock_t *)SB_LOCK_ADDRESS);		//开锁
    printk("The number of inodes: %llu\n",sizeof(struct inode) *count);
    return 0;
}

static void __exit my_exit(void)
{
    printk("unloading...\n");
}

module_init(my_init);
module_exit(my_exit);
MODULE_LICENSE("GPL");

运行结果:

在这里插入图片描述

二、问答

1. mount机制与超级块是什么关系,与文件系统的类型又是什么关系?

​ 将一个文件系统的顶层目录挂到另一个文件系统的子目录上,使他们成为一个整体,称为”mount(安装)”,linux内核采用VFS框架来组织文件系统,每个文件系统用一个超级块(super_block)数据结构来描述,每个注册的文件系统,对应着相应的超级块对象。

​ 若两个都为xfs文件系统,则xfs的file_system_type的fs_supers把两个同为xfs文件系统的super_block串连在自己下面。另一个minix文件系统没挂载使用,所以没他的super_block信息被读入内存。一个文件系统对应一个super_block,所以同一个文件系统当然只有一个super_block。但是因为挂载了两次,所有每一次挂载对应一个挂载实例struct mount,也就是有两个mount实例。

2. inode是如何分配的?磁盘inode和内存inode有什么区别?

​ linux文件系统使用索引节点来记录文件信息,系统给每个索引节点分配一个号码。Linux采用一种叫做Orlov allocator的算法来负责选择inode的位置。在linux中,文件的内容和属性是分离的,inode用来保存文件属性的结构。通常情况,一个文件一个inode,一个inode号。操作任何一个文件都是在特定目录下查找的,目录也是文件,所以目录里存放的是目录下所有文件的文件名和inode的映射关系。尽可能使得一个文件的数据和其inode在相同的块组中,这种方法减少了data寻址耗时,特别是刚刚读取inode后就访问数据这种场景。
img

​ 磁盘inode和内存inode的区别:

​ (1)内存中的inode: VFS inode包含文件访问权限、属主、组、大小、生成时间、访问时间、最后修改时间等信息。磁盘上的inode:EXT2通过使用inode来定义文件系统的结构以及描述系统中每个文件的管理信息,每个文件都有一个inode且只有一个,即使文件中没有数据,其索引结点也是存在的。

​ (2)位置:VFS inode结构位于内存中,而Ext2_inode位于磁盘。

​ (3)生存期:VFS inode在需要时才会被建立,如果系统断电,此结构也随之消失。而Ext2_inode的存在与系统是否上电无关,而且无论文件是否包含数据,Ext2_inode都是存在的。

​ (4)唯一性:两者在自己的作用域中都是唯一的。

​ (5)关系:VFS inode是Ext2 inode的抽象、映射与扩充,而后者是前者的静态信息部分,也是对前者的具体化、实例化和持久化。

​ (6)操作:对VFS inode的操作具有通用性,对文件系统inode的操作则是文件系统相关的,依赖于特定的实现。

​ (7)组织管理:系统通过VFS inode链表来对其进行组织,并且为了提高访问效率相应地构造了inode构造缓存和hash table。Ext2 inode的信息位于EXT2文件系统的划分的块组中,在每个块组中包含相应的inode位图、inode表指定具体的inode信息,每个inode对应Ext2_inode结构。

3. 有了inode,为什么还要dentry? 如果没有denrty,会出现什么情况?

​ 所谓"文件", 就是按一定的形式存储在介质上的信息,所以一个文件其实包含了两方面的信息,一是存储的数据本身,二是有关该文件的组织和管理的信息。内存中,每个文件都有dentry(目录项)和inode(索引节点)结构,dentry记录着文件名,上级目录等信息,正是它形成了我们所看到的树状结构;该文件的组织和管理的信息主要存放inode里面,它记录着文件在存储介质上的位置与分布。
​ 因为有可能一个文件有好几个文件名,所以有inode,还要有dentry,dentry与inode是多对一的关系。
​ 如果没有dentry可能会出现的情况是,根据inode找到了文件位置,但不知道其文件名、上级目录等信息。

4. files_struct结构和file结构是什么关系,如果没有file结构是否可以?

​ files_struct结构和file结构的关系如下图:

在这里插入图片描述

​ 没有file结构的话就无法记录文件和进程交互的信息以及一些文件操作,将file对象f_op指向了所属文件系统的操作函数集file_operations,而该函数集又来自具体文件的inode,于是虚拟文件系统就与实际文件系统的操作就衔接起来了。

5.为什么要有一个fs_strcut结构?

​ 如上图,fs字段指向fs_struct结构体,是用来记录这个进程的工作目录pwd,和它的根目录root, 每个进程都有自己的根目录和当前工作目录,fs_struct来记录这些信息。显然目录信息是由dentry结构体保存的;在linux中,目录也是一种文件,因此dentry结构体会有指向inode结构体的指针字段d_inode。

猜你喜欢

转载自blog.csdn.net/qq_58538265/article/details/133915781
今日推荐