写个文件系统

0.
  终于在期末考试之前对vfs层和相关文件系统有了大致到稍细致的研究,故写个文件系统来总结下
 
1.用户态文件系统
  如果单纯写个文件系统,只是对特定文件系统的在磁盘设备上结构组成有细致了解就好了,比方说给你一个磁盘上面已经有了
一个完好的ext2文件系统,让你对他进行常规文件操作,你当然可以用mount -t ext2 /dev/<device file> <dir>命令挂载,
然后进入<dir>再用常规命令操作文件即可。
  但真要简单的话,只要写个用户态程序对/dev/<device file>进行常规读写再按照特定文件系统格式对读写出来的数据进行解析
处理,一样可以做到。简单的读写minix文件系统的用户态程序,只要参考了linux 0.11的fs相关代码,可以做到目录创建,读,删除
和文件的读写,创建,删除等操作。
 
2.基于内存的(虚拟)文件系统
  内核中有许多基于内存的虚拟文件系统,如proc/sys等等,在这些当中有个非常简单的内存文件系统ramfs,如果你想试验可以:
 #mount -t ramfs ramfs <dir>
 #cd <dir>
 #<Just for fun!>
  而ramfs代码就位于 kernelsrc/fs/ramfs中,其中代码量相对较少,主要是ramfs利用了很多内核中现成的文件读写API。
  现在我们能想到什么?既然ramfs可以构建自己文件系统,当然我们也可以,并且可以写成lkm模块插入内核,然后挂载自己的
  文件系统到某个目录,然后看看能不能实现常规文件操作。
 
  需要的帮助是什么?只需要内核源代码,这里你可以参考proc和ramfs的实现。
  (proc中那些进程相关的目录有着特殊的操作,涉及到pid_namespace,为了简单可以跳过)
  我们要做的就是将心中所设想的文件系统按照内核提供的套路和api来实现即可。主要说下大体coding的思路:
  (以simp_xxx开头的函数都是内核要求我们写的,只是我起了名字:)
   1)初始化:
     定义file_system_type结构simp_fs_type(其中flag域设置0,即表明不需要磁盘等实体设备), 
     用内核函数register_filesystem注册它。
     另外设计自己目录项结构和inode结构,并申请一些内存cache做结构缓冲区(也可以使用内核原生的dentry 和 inode).
   2)挂载相关:
     如果第1)步做好,我们就可以把代码编译成.ko插入内核了, 然后 mount -t simp simp <dir>了,但是事实并没这么简单,
     之所以能够mount成功,完全依赖于1)中file_system_type结构完整性,我们要为file_system_type.get_sb
     附上一个函数指针,即写一个simp_get_sb函数,目的是在mount中被系统调用到,来分配和初始化我们自己文件系统的超级块
     另外你当然要了解sys_mount的具体实现以便更好的写出simp_get_sb这个函数,要做的就是读源码,然后去写。
   3)路径搜索lookup:
     说真的,这部分是文件系统中最让人看着心烦的,大量遍历和字符串操作,大体就是给你个路径“/home/Eruda/dir” 然后让你
     遍历路径找到dir目录的目录项dentry.
     如果这步定位没做到,那就不用扯什么文件操作了,还好内核已经帮我们做了很多,这里只要留意一个函数:
     simp_lookup,此函数内你不需要做太多,但一定要返回NULL,如果返回非NULL表示内核路径搜索都没找到dentry,而你却在
     自己的文件系统里面找到dentry,那么内核就不会为我们创建一个新的dentry,即文件创建的操作必将失败(除非做文件隐藏)。
   4)属性stat:
     这个也比较简单但是却很重要,因为上层应用软件在做任何文件操作前都会对文件做stat操作,即请求文件属性,如果不能正确
     处理这个系统调用,那么上层软件认为文件属性不正确,就不会进一步做文件操作处理。
   5)各种文件相关系统调用:
     由于内核中在具体文件系统上有vfs层的存在,采用了OO的思想,即文件操作函数作为文件属性捆绑到file结构或inode结构上,
     即所有文件操作函数都集中在inode_operations/file_operations这两种函数指针集的结构中,包括了3),4)中2个函数
     也位于其中,那么剩下的文件操作任务:创建,删除,读写等等就是由我们自己构造的函数来实现了,这部分是最大分量最有趣的!
    
3.基于设备的文件系统
  如果写一个基于内存的文件设备不过瘾,那么基于设备的文件系统一定能给我们真实的体验。
  大体的coding过程如2中步骤,但这里有少许区别:
  1)要有具体文件系统的在磁盘上构成,可以自己设计个超简单的文件系统,也可以为现有文件系统写个驱动,ext2不错的选择,
     在有了对minix了解,过度到ext2很自然
  2)要有格式化程序,就是实现要有已经具有文件系统结构的磁盘。如果没有就要自己创建个,这时就要用到格式化程序,
       就是常用的mkfs.xxxx命令
     如果手边没有磁盘或不想格式化分区可以这么做来构建磁盘设备:
     #dd if=/dev/zero of=./data bs=1024 count=1024     //用普通文件模拟磁盘设备(这里模拟10M的磁盘设备)
     #mkfs.ext2 ./data                                                      //格式化
     #mount -t ext2 ./data -o loop test_mount_dir/         //将文件关联到loop设备,然后将loop设备挂在到目录上
     (最后一步也可以这样
            #losetup  /dev/loopX  ./data                              // *参数不要弄反了*

 

            #mount -t ext2 /dev/loopX test_mount_dir/
     )
  3)在内核中相关文件操作要涉及读磁盘设备的地方用sb_bread内核函数
 
---------------------
涉及到太多内核代码,只有去读才能明白,不是很容易讲出来
恩,这样一套下来,简单文件隐藏实在是很好做,都有了自己的文件系统,那么文件也就在我们手中控制了:)

 

 

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值