在简单的介绍文件系统之前一定要先简单的说明一下物理的存储介质。为什么要介绍物理存储介质呢?
主要是为了说明“everything is files”。好吧……既然大家知道一切皆文件了,我们在此就不介绍物理存储介质了。但是还是希望大家能够对物理的介质进行读写操作,真正的感受下,读取文件系统第一个分区的第一个扇区的感觉。这样便于我们理解文件系统的概念。
首先我们查看下在设备上的/dev/block目录,因为磁盘作为块设备就存在于这个文件下。在板子上,会是MMC开头的文件。例如mmcblk0即为第一个分区,而此分区又分成了mmcblk0p1……。我们在读取分区信息的时候只需要,读取mmcblk0的前512字节的数据并按照十六进制的方式输出即可。
在linux中支持这很不同格式的文件系统,而这些文件系统相互之间怎样进行通信便成了一个很大的问题,当我们需要对数据今次那个cp的时候,我们需要知道“源文件系统”和“目的文件系统”。这样进行两种文件系统的一次拷贝过程也许消耗资源不多,但是我们如果频繁的进行不同的文件系统之间的数据拷贝时,就不能忽略对资源的消耗了。因此,我们必须要采取适当的措施把这种复杂的过程抽象出来形成单独的部分,这种情况下便产生了虚拟文件系统VFS。
VFS是什么?
请自行查阅。
这里不得不提一下,FUSE。FUSE(file system in user space)提供了一种在用户空间实现自己的文件系统的平台。我们可以借助这个文件系统完成自己的文件系统的扩展。具体内容自行查阅。此处比较出名的应用就是实现了linux对NTFS格式文件的支持。
一点差异
2.4内核中貌似维护了一个文件系统的目录,而在2.6内核中本人并没有发现。
在2.6内核中,文件系统中,在启动的过程中,文件系统会对驱动进行注册,完成注册之后,会在后续的时间里,完成对设备的扫描并且根据设备的类型进行轮询。当轮询的过程,发现设备插入时就会将设备与驱动类型进行匹配,如果能够匹配在mount成功,否则mount失败并报告相应的错误。
2118 SYSCALL_DEFINE5(mount, char __user *, dev_name, char __user *, dir_name,
2119 char __user *, type, unsigned long, flags, void __user *, data)
2120 {
2121 int ret;
2122 char *kernel_type;
2123 char *kernel_dir;
2124 char *kernel_dev;
2125 unsigned long data_page;
2126
2127 ret = copy_mount_string(type, &kernel_type);
2128 if (ret < 0)
2129 goto out_type;
2130
2131 kernel_dir = getname(dir_name);
2132 if (IS_ERR(kernel_dir)) {
2133 ret = PTR_ERR(kernel_dir);
2134 goto out_dir;
2135 }
2136
2137 ret = copy_mount_string(dev_name, &kernel_dev);
2138 if (ret < 0)
2139 goto out_dev;
2140
2141 ret = copy_mount_options(data, &data_page);
2142 if (ret < 0)
2143 goto out_data;
2144
2145 ret = do_mount(kernel_dev, kernel_dir, kernel_type, flags,
2146 (void *) data_page);
2147
2148 free_page(data_page);
2149 out_data:
2150 kfree(kernel_dev);
2151 out_dev:
2152 putname(kernel_dir);
2153 out_dir:
2154 kfree(kernel_type);
2155 out_type:
2156 return ret;
2157 }
这就是内核中文件系统mount的入口宏定义函数。在此函数中的do_mount()、do_remount()、do_newmount()函数会帮你完成你想要完成的任务,你只需要坐着喝茶就好。