前言

该从哪里开始说文件系统呢?可能很多人有不同的见解,可能有人喜欢从一个具体文件系统的on-disk结构开始说,有人喜欢从VFS的基本元素开始说,我比较倾向从挂载一个文件系统开始。应该说各有利弊吧,上来就说on-disk结构,就像上来就背一堆公式告诉你以后用一样会一头雾水。先说VFS层inode, super block, dentry, file等概念的话,也很难理解其到底对应什么。直接从mount开始说的话,离开VFS的基本概念可能理解起来会有些困难。所以最好先对VFS层的基本数据结构有一些了解但不用太深入,那样最好了。所以阅读此文的前期要求是:

先了解dentry, inode, superblock这三个基本概念

如果你对此一无所知,那请看过后再来。我下面会用一句话简单带过这三个概念,起一个头:

Superblock: 常缩写为sb(还好老外不懂中文),是一个文件系统的头部,一般在一个文件系统的第一个block里,存储着文件系统的最主要信息,如文件系统名称,大小,块大小,inode大小,有多少inode已用和未用,有多少空闲block等等。与on-disk的superblock对应。

inode: 一个inode对应一个客体文件(或目录),携带这个文件的所有元信息,包括文件属性、占用空间等信息。其与On-disk的inode对应。

dentry: 是directory entry的缩写,是一个抽象话概念,不对应On-disk结构(或者你把路径信息理解成dentry,当然这个不严谨)。从其字面意思也可以看出它是内核为构建和访问目录树形结构服务的,是目录与其下文件的缓存,主要信息包括文件名和其parent目录名。一个dentry链表常常是可以从一个文件向上追踪其每一个parent directory,直到root。注意,在内核中可能出现多个dentries结构对应一个inode,比如硬链接就是两个不同名的文件对应一个inode。

好了,多说无用,想具体了解还是自己去看书看代码吧。我不可能用几句话就让你知道这些是什么。在讲到mount操作之前,需要先知道一个文件系统模块是怎么和内核关联起来的,好让内核可以在文件系统挂载时准确找到这个文件系统的模块。所以我们的第一个概念从一个叫file_system_type的概念开始说。

file_system_type

先来看一下定义(来自Linux v4.17-rc2):

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_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;
};

来看一下主要域的意思(个别说明不一定完全准确):

name: 文件系统的名字,如xfs, ext2等

fs_flags: 说明文件系统的类型,下面的宏定义代表了它的几种类型:

  • FS_REQUIRES_DEV: 文件系统必须在物理设备上。
  • FS_BINARY_MOUNTDATA: mount此文件系统时(参见mount_fs函数 - fs/super.c)需要使用二进制数据结构的mount data(如每个位域都有固定的位置和意义),常见的nfs使用这种mount data(参见struct nfs_mount_data结构 - include/uapi/linux/nfs_mount.h)。
  • FS_HAS_SUBTYPE: 文件系统含有子类型,最常见的就是FUSE,FUSE本是不是真正的文件系统,所以要通过子文件系统类型来区别通过FUSE接口实现的不同文件系统。
  • FS_USERNS_MOUNT: 文件系统每次挂载都后都是不同的user namespace,如用于devpts。
  • FS_RENAME_DOES_D_MOVE: 文件系统将把重命名操作reame()直接按照移动操作d_move()来处理,主要用于网络文件系统。

mount: 代替早期的get_sb(),用户挂载此文件系统时使用的回调函数。

kill_sb: 删除内存中的super block,在卸载文件系统时使用。

owner: 指向实现这个文件系统的模块,通常为THIS_MODULE宏。

next: 指向文件系统类型链表的下一个文件系统类型。

fs_supers: 此文件系统类型的文件系统超级块结构都串连在这个表头下。

对于一个文件系统,定义好自己的file_system_type结构后就需要将自己注册进内核。

register_filesystem

参考fs/filesystem.c,这个文件不长,在开头有一个重要的全局变量:

static struct file_system_type *file_systems;

这个指针将指向所有已注册的文件系统模块。

看过这个全局变量后我们接着看register_filesystem函数,其定义与解释都也很详细,如下(来自Linux 4.17-rc2, fs/filesystem.c)

/***      register_filesystem - register a new filesystem*      @fs: the file system structure**      Adds the file system passed to the list of file systems the kernel*      is aware of for mount and other syscalls. Returns 0 on success,*      or a negative errno code on an error.**      The &struct file_system_type that is passed is linked into the kernel *      structures and must not be freed until the file system has been*      unregistered.*/int register_filesystem(struct file_system_type * fs)
{int res = 0;struct file_system_type ** p;BUG_ON(strchr(fs->name, '.'));if (fs->next)return -EBUSY;write_lock(&file_systems_lock);p = find_filesystem(fs->name, strlen(fs->name));if (*p)res = -EBUSY;else*p = fs;write_unlock(&file_systems_lock);return res;
}

里面最主要的逻辑是find_filesystem调用及指针p的处理。先来看find_filesystem的定义:

static struct file_system_type **find_filesystem(const char *name, unsigned len)
{struct file_system_type **p;for (p = &file_systems; *p; p = &(*p)->next)if (strncmp((*p)->name, name, len) == 0 &&!(*p)->name[len])break;return p;
}

for循环一开始的file_systems变量,就是我们上面说的存储着所有已注册文件系统的全局指针。strncmp调用也很明确,就是比较file_system_type的第一项name(文件系统名)和要注册的文件系统名字是否相同。就这样一直找,如果找到同名的,break的时候p就是指向找到的同名file_system_type结构的指针,如果没找到就是指向NULL的指针(注意p本身不是NULL)。

在返回register_filesystem函数后,判断返回值,如果找到重复的则返回EBUSY错误,如果没找到重复的,就把当前要注册的文件系统挂到尾端file_system_type的next指针上,串联进链表。至此一个文件系统模块就注册好了。

当然与register相对应的就是unregister函数,这里就不说它了。在fs/filesystem.c里还有一个很重要的函数是get_fs_type(),它接受一个文件系统的名称作为参数,然后反向找到其对应的file_system_type实例,这个在mount的时候是很常用的。

说了怎么注册一个文件系统,那一个具体的文件系统的file_systemtype长什么样呢?

我们以XFS的为例看一下(Linux 4.17-rc2 fs/xfs/xfs_super.c):

static struct file_system_type xfs_fs_type = {.owner                  = THIS_MODULE,.name                   = "xfs",.mount                  = xfs_fs_mount,.kill_sb                = kill_block_super,.fs_flags               = FS_REQUIRES_DEV,
};

这是XFS的file_systemtype的实例,name表明其是xfs,fsflags表明其是必须用在存储设备上的文件系统,不是虚拟文件系统等。最重要的两个回调函数"mount"和"killsb"就是两个需要XFS模块来实现的带有具体细节的函数了。mount是在mount操作时会被调用的函数,kill_sb一般会在umount的时候使用。这里就不展开展开具体细节了,留到后面说到具体mount操作时再说。

至此我们了解了file_system_type,已经如何注册使用。一个file_system_type最主要告诉内核三件事:“我叫什么”,“怎么挂载我”以及“怎么卸载我”(多么纯粹的让人感动:)。


更多内容请参阅:

醉卧沙场:README - 专栏文章总索引

system volume information怎么删除_文件系统怎么让Linux内核认识自己相关推荐

  1. win7系统system volume information如何删除--wom7w.com

    我们在win7系统当中能够发现,每个磁盘下都会有一个system volume information文件,这个文件是隐藏的,而且还带有一个锁,这是是windows系统的还原文件夹,既占用磁盘空间,而 ...

  2. U盘中毒,无法删除System Volume Information文件夹

    情景:U盘中毒,U盘内的文件夹名称变成.exe后缀,且多出一个名为System Volume Information的文件夹,对U盘进行格式化后,所有文件消失,当拔出U盘,再次插入电脑时,发现Syst ...

  3. U盘中毒了?教你如何删除System Volume Information这个顽固文件夹

    不得不说cmd命令很好用呢.最近我的U盘中毒了,格式化都删除不了System Volume Information这个顽固的文件夹,真心伤不起哇!还好现在解决了问题.看来以后得好好对待U盘,不能乱用了 ...

  4. 优盘中毒,里面有(System Volume Information文件夹)删除不了?教你怎么解决

    又发现我的优盘里面还有其他东西... 这次是个System Volume Information文件夹,怎么删都删不了,学校的打印店电脑不要乱插!!! 解决步骤 输入以下命令 重置隐藏文件(E为E盘, ...

  5. 非常规方法彻底删除System Volume Information.exe

    1.进入PE系统. 2.在PE系统硬盘管理系统内找到U盘. 3.删除分区. 4.新建分区. 5.重启电脑,插入U盘,你就会发现System Volume Information.exe删除的干干净净啦 ...

  6. 删除U盘中的System Volume Information 文件夹的方法

    在使用U盘测试ARM板的时候,会发现System Volume Information这个文件夹阴魂不散,总是存在,在Windows下是看不见的,即便将文件的查看属性设置为显示隐藏文件. 在使用U盘进 ...

  7. 小小知识点(十八)U盘中病毒了,System Volume Information文件夹删除不掉

    win+R调出命令窗口后搜索cmd,启用cmd命令编辑器,并输入以下命令: attrib "H:\System Volume Information" -s   //这句话可以选择 ...

  8. 如何删除U盘中System Volume Information文件夹

    教你如何删除System Volume Information这个顽固文件夹 我的电脑是win10,win+R搜索cmd,启用cmd命令编辑器,并按顺序输入以下命令: 1. attrib " ...

  9. u盘中毒如何删除system volume information文件

    最近U盘因为插别人的电脑上中毒了,出现了System Volume Information文件夹,然后搜了相关解决方法,确实有效,但由于大家写的都太相似了,没有考虑到每台计算机的具体状况,感觉对新手小 ...

最新文章

  1. 裂痕第一至五季/以法之名Damages迅雷下载
  2. 学python编程_学习Python编程,我们应该如何学?学习内容包括哪些?
  3. NPAPI和PPAPI开发
  4. ZNZD平台vue项目
  5. Python判断变量的数据类型的两种方法
  6. 桌面SVN检出这一选项消失
  7. 华为海思年内恐超越联发科 成亚洲最大芯片设计公司
  8. Python实例讲解 -- tkinter canvas (设置背景图片及文字)
  9. NLP《词汇表示方法(五)GloVe》
  10. day31 java的多线程(1)
  11. [Linux] LD_LIBRARY_PATH
  12. c+mysql+sslmode_MySQL配置SSL主从复制
  13. ue html乱码,UE UTF8 乱码
  14. 我的CCNA笔记(二)
  15. 单应性变换、仿射变换、透视变换
  16. 我要写整个中文互联网界最牛逼的JVM系列教程 | 「JVM与Java体系架构」章节:官方规范下载与参考书目
  17. true launch bar 和 editplus
  18. 李春江:决赛是期待和希望,希望小丁早日康复
  19. Vue + Element UI 实现权限管理系统(更换皮肤主题)
  20. 高通发布了全球最领先的5G基带芯片,不过华为将很快反超

热门文章

  1. dubbox 编译 和 测试
  2. highcharts使用教程
  3. IIS6.0上某些文件类型不能下载
  4. Wijmo 更优美的jQuery UI部件集:通过jsFiddle测试Wijmo Gauges
  5. python模块之email: 电子邮件编码解码 (二、编码邮件)
  6. Jenkins报错‘Gradle build daemon disappeared unexpectedly‘的问题解决
  7. Python 下载依赖包环境经常失败超时解决方法
  8. 关于“Cannot find any provider supporting AES/ECB/PKCS7Padding”问题的解决方案
  9. 解决启动mysql.exe闪退问题
  10. linux配置静态IP后ping外网不通的解决方案