关于文件系统的一些心得(ramfs),纯扯淡和流水账

       在linux初始化的时候,start_kernel中有vfs_caches_init这么一个函数调用,其中mnt_init这个函数里是初始化全局文件系统的,sysfs这个文件系统,这个文件系统是一些设备总线信息的;至于全局文件系统则是调用这个init_mount_tree();这个函数。我手上的代码中rootfs即为ramfs。

      文件系统中有超级块(super block(代码中有时候缩写成sb)),目录项(dentry),节点(inode)。个人是这么理解这三个东西的,sb是一个文件系统的象征,有且只有一个,如果一个文件系统看做一颗树的话,sb就相当于根节点,在同一文件系统中的dentry,inode所指向的sb均指向同一sb。至于目录项,linux下无论是文件还是目录均是目录项,也就任何一个文件,其实都有一个dentry指向于它。inode的话,就是存放数据的地方,比如inode->mapping->page_tree上存放着数据的page,这个page可以通过index找到。也就是说在ramfs中数据其实都是存放在page上的,而怎么找到这个page呢,我们首先要知道dentry,dentry->d_inode得到inode,inode再通过传入的pos之类(可参见read过程)的,计算得到index,这样就可以得到page了。

      还有linux的fork函数中,最终调用的do_fork中的copy_process,if ((retval = copy_fs(clone_flags, p)))这个函数将当前函数的fs(文件系统)copy给了新的进程,fs->rootmnt = mntget(old->rootmnt);fs->root = dget(old->root);fs->pwdmnt = mntget(old->pwdmnt);fs->pwd = dget(old->pwd);因为task_struct->fs只是个指针,所以可以由上面的几个代码可得,新的fs其实与oldfs指向的是同一个mnt和root,也就是说他们都指向了第一个的mnt和root,也就是上面所说start_kernel所创建的root,mnt,这使得看上去不同进程操作同一个文件系统,看上去像是同步的,实嘛他们都在操作同一个区域,不一样才怪了呢。同一个dentry,sb,mnt,inode。

       至于文件结构filp的话,它是这样的,get_empty_filp()这个函数里可以得到一个尚未使用的file结构,其实这个file是被alloc出来的,至于fd(文件描述符)就更单纯了,从0开始查找,发现有尚未使用的数字,拿来就做fd。这些都在open的时候搞定的。

接下来用一个图可以比较形象的了解这一些东西。


   不同进程之间创建file对象,他们的fd可以各不相同,因为这些都是他们自己alloc出来的,但是他们指向的dentry都在同一个区域块里(同一个文件系统里的mnt和root),dentry再指向inode,然后再是数据。简单归纳一下,各个进程除了fd和file可以各有差异,他们的dentry和inode都是同一个,同一个。图中看上去不同的dentry可以理解成快捷方式,link。

   在ramfs中文件的读写,其实都是一页页内存的读写,inode->mapping->page_tree。

   如果要挂其他文件系统上去,可以用mount,比如在系统刚起来的时候,preinit:21:mount -n -t proc /proc /proc   preinit:22:mount -n -t sysfs sysfs /sys  这个已经在busybox的init里面了,就是proc和sysfs这两个文件系统给挂载至rootfs上。

你可能感兴趣的:(linux内核)