linux文件系统的系统分析--(二)文件系统类型的注册



 因为Linux支持模块机制,所以我们可以将文件系统编译为模块,所以文件系统系统类型的注册的注册有多种方式:要么已经包含在内核映像中,要么作为一个模块被动态加载。我们关注的重点是rootfs和sysfs,他们其实在系统初始化的时候就注册并安装好了,没有rootfs,linux就没法玩了。以rootfs的注册为例,来分析一下文件系统类型的注册:

        在start_kernel-->vfs_caches_init(totalram_pages);

        vfs_caches_init函数如下:

[cpp]   view plain  copy
  1. void __init vfs_caches_init(unsigned long mempages)  
  2. {  
  3.     unsigned long reserve;  
  4.   
  5.     /* Base hash sizes on available memory, with a reserve equal to 
  6.            150% of current kernel size */  
  7.   
  8.     reserve = min((mempages - nr_free_pages()) * 3/2, mempages - 1);  
  9.     mempages -= reserve;  
  10.   
  11.     names_cachep = kmem_cache_create("names_cache", PATH_MAX, 0,  
  12.             SLAB_HWCACHE_ALIGN|SLAB_PANIC, NULL);  
  13.   
  14.     dcache_init();  
  15.     inode_init();  
  16.     files_init(mempages);  
  17.     mnt_init();  
  18.     bdev_cache_init();  
  19.     chrdev_init();  
  20. }  
        其中: dcache_init();   //目录项的缓存
                inode_init();      //索引节点的缓存
                files_init(mempages);   //file的缓存
                mnt_init();
                bdev_cache_init();       //块设备的缓存
                chrdev_init();             //字符设备的初始化,在《 linux设备模型之字符设备 》中会看到字符设备文件是如何建立的。

        目前我们关注的重点是mnt_init(),其中有这么几行代码:

[cpp]   view plain  copy
  1. err = sysfs_init();  
  2. if (err)  
  3.     printk(KERN_WARNING "%s: sysfs_init error: %d\n",  
  4.         __func__, err);  
  5. fs_kobj = kobject_create_and_add("fs", NULL);  
  6. if (!fs_kobj)  
  7.     printk(KERN_WARNING "%s: kobj create error\n", __func__);  
  8. init_rootfs();  
  9. init_mount_tree();  
         可以看到,sysfs_init还在init_rootfs之前,是不是有点奇怪,没有root fs,哪有其他的fs啊?这个在后面我们会明白。

         这一次我们只看init_rootfs():

         在fs/ramfs/inode.c中:

[cpp]   view plain  copy
  1. int __init init_rootfs(void)  
  2. {  
  3.     int err;  
  4.   
  5.     err = bdi_init(&ramfs_backing_dev_info);  
  6.     if (err)  
  7.         return err;  
  8.   
  9.     err = register_filesystem(&rootfs_fs_type);  
  10.     if (err)  
  11.         bdi_destroy(&ramfs_backing_dev_info);  
  12.   
  13.     return err;  
  14. }  
          register_filesystem(&rootfs_fs_type);完成文件系统的注册:

[cpp]   view plain  copy
  1. static struct file_system_type rootfs_fs_type = {  
  2.     .name       = "rootfs",  
  3.     .get_sb     = rootfs_get_sb,  
  4.     .kill_sb    = kill_litter_super,  
  5. };  
          rootfs_fs_type是一个file_system_type类型的结构体,主要的函数是get_sb--rootfs_get_sb函数,作用是获取rootfs文件系统的超级块对象。

          其实这个注册过程很简单,其实就是加入链表的过程:

          为了证明链表的存在:还是要给出file_system_type结构体的全貌:

          

[cpp]   view plain  copy
  1. struct file_system_type {  
  2.     const char *name;  
  3.     int fs_flags;  
  4.     int (*get_sb) (struct file_system_type *, int,  
  5.                const char *, void *, struct vfsmount *);  
  6.     void (*kill_sb) (struct super_block *);  
  7.     struct module *owner;  
  8.     struct file_system_type * next;  
  9.     struct list_head fs_supers;  
  10.   
  11.     struct lock_class_key s_lock_key;  
  12.     struct lock_class_key s_umount_key;  
  13.   
  14.     struct lock_class_key i_lock_key;  
  15.     struct lock_class_key i_mutex_key;  
  16.     struct lock_class_key i_mutex_dir_key;  
  17.     struct lock_class_key i_alloc_sem_key;  
  18. };  

          仔细看一下这个结构体,可以看到貌似有两个链表:struct file_system_type * next;单项链表和struct list_head fs_supers;这个linux内核经典的双向链表。

          往后,我们会看到这两个链表各自是怎么串的,串的是什么内容。而在register_filesystem中我们就可以看到struct file_system_type * next;单项链表的形成。

          register_filesystem函数如下:

[cpp]   view plain  copy
  1. int register_filesystem(struct file_system_type * fs)  
  2. {  
  3.     int res = 0;  
  4.     struct file_system_type ** p;  
  5.   
  6.     BUG_ON(strchr(fs->name, '.'));  
  7.     if (fs->next)  
  8.         return -EBUSY;       //1  
  9.     INIT_LIST_HEAD(&fs->fs_supers);      //2  
  10.     write_lock(&file_systems_lock);  
  11.     p = find_filesystem(fs->name, strlen(fs->name));   //3  
  12.     if (*p)  
  13.         res = -EBUSY;  
  14.     else  
  15.         *p = fs;  
  16.     write_unlock(&file_systems_lock);  
  17.     return res;  
  18. }  
           1、如果文件系统已经注册了,那么无法在注册了。每种类型的文件系统只能注册一次,但是可以有多种设备使用同一个类型的文件系统,也可以将同一类型的文件系统              挂载在不同的路径下。

           2、初始化fs->fs_supers;

           3、将即将注册的文件系统放在链表的尾部:

           find_filesystem函数如下:

[cpp]   view plain  copy
  1. static struct file_system_type **find_filesystem(const char *name, unsigned len)  
  2. {  
  3.     struct file_system_type **p;  
  4.     for (p=&file_systems; *p; p=&(*p)->next)  
  5.         if (strlen((*p)->name) == len &&  
  6.             strncmp((*p)->name, name, len) == 0)  
  7.             break;  
  8.     return p;  
  9. }  

            可以清楚的看到:通过二级指针来遍历当前的链表,并将文件系统类型通过next指针挂载链表尾部,链表头为file_systems。

            到此,文件系统类型的注册就结束了,简单说:就是将文件类型加入以file_systems为表头的单向链表中。

转自http://blog.csdn.net/dndxhej/article/details/7423585

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值