Chinaunix首页 | 论坛 | 博客
  • 博客访问: 434290
  • 博文数量: 99
  • 博客积分: 65
  • 博客等级: 民兵
  • 技术积分: 1012
  • 用 户 组: 普通用户
  • 注册时间: 2012-04-20 16:30
个人简介

linux kernel 工程师

文章分类

全部博文(99)

文章存档

2018年(5)

2017年(12)

2016年(27)

2015年(10)

2014年(43)

2012年(2)

我的朋友

分类: LINUX

2016-12-29 17:40:02


点击(此处)折叠或打开

  1. /**
  2.  *    sget    -    find or create a superblock
  3.  *    @type:    filesystem type superblock should belong to
  4.  *    @test:    comparison callback
  5.  *    @set:    setup callback
  6.  *    @data:    argument to each of them
  7.  */
  8. /* test: proc_test_super
  9.    set: proc_set_super
  10.  */
  11. struct super_block *sget(struct file_system_type *type,
  12.             int (*test)(struct super_block *,void *),
  13.             int (*set)(struct super_block *,void *),
  14.             void *data)
  15. {
  16.     struct super_block *s = NULL;
  17.     struct super_block *old;
  18.     int err;

  19. retry:
  20.     spin_lock(&sb_lock);
  21.     if (test) {
  22.         /* 在proc_root_init中调用register_filesystem时将proc_fs_type->fs_supers初始化了
  23.             proc_fs_type->fs_supers->next=proc_fs_type->fs_uspers
  24.             proc_fs_type->fs_supers->prev=proc_fs_type->fs_uspers
  25.         */
  26.         list_for_each_entry(old, &type->fs_supers, s_instances) {
  27.             if (!test(old, data))
  28.                 continue;
  29.             if (!grab_super(old))
  30.                 goto retry;
  31.             if (s) {
  32.                 up_write(&s->s_umount);
  33.                 destroy_super(s);
  34.                 s = NULL;
  35.             }
  36.             if (unlikely(!(old->s_flags & MS_BORN))) {
  37.                 deactivate_locked_super(old);
  38.                 goto retry;
  39.             }
  40.             return old;
  41.         }
  42.     }
  43.     if (!s) {
  44.         spin_unlock(&sb_lock);
  45.         s = alloc_super(type);
  46.         if (!s)
  47.             return ERR_PTR(-ENOMEM);
  48.         goto retry;
  49.     }
  50.         
  51.     err = set(s, data);
  52.     if (err) {
  53.         spin_unlock(&sb_lock);
  54.         up_write(&s->s_umount);
  55.         destroy_super(s);
  56.         return ERR_PTR(err);
  57.     }
  58.     s->s_type = type;
  59.     strlcpy(s->s_id, type->name, sizeof(s->s_id));
  60.     list_add_tail(&s->s_list, &super_blocks);
  61.     list_add(&s->s_instances, &type->fs_supers);
  62.     spin_unlock(&sb_lock);
  63.     get_filesystem(type);
  64.     return s;
  65. }

点击(此处)折叠或打开

  1. static int proc_get_sb(struct file_system_type *fs_type,
  2.     int flags, const char *dev_name, void *data, struct vfsmount *mnt)
  3. {
  4.     int err;
  5.     struct super_block *sb;
  6.     struct pid_namespace *ns;
  7.     struct proc_inode *ei;

  8.     /* proc_root_init->kern_mount_data->vfs_kern_mount时传递了该标志 */
  9.     if (flags & MS_KERNMOUNT)
  10.         ns = (struct pid_namespace *)data;
  11.     else
  12.         ns = task_active_pid_ns(current);

  13.     sb = sget(fs_type, proc_test_super, proc_set_super, ns);
  14.     if (IS_ERR(sb))
  15.         return PTR_ERR(sb);

  16.     if (!sb->s_root) {
  17.         sb->s_flags = flags;
  18.         err = proc_fill_super(sb);
  19.         if (err) {
  20.             deactivate_locked_super(sb);
  21.             return err;
  22.         }

  23.         sb->s_flags |= MS_ACTIVE;
  24.         ns->proc_mnt = mnt;
  25.     }

  26.     /* Ensure the root directory has it's associated pid. */
  27.     ei = PROC_I(sb->s_root->d_inode);
  28.     if (!ei->pid) {
  29.         rcu_read_lock();
  30.         ei->pid = get_pid(find_pid_ns(1, ns));
  31.         rcu_read_unlock();
  32.     }

  33.     simple_set_mnt(mnt, sb);
  34.     return 0;
  35. }

点击(此处)折叠或打开

  1. static struct file_system_type proc_fs_type = {
  2.     .name        = "proc",
  3.     .get_sb        = proc_get_sb,/* 这是vfs_kern_mount里面调用读取suberblock的函数 */
  4.     .kill_sb    = proc_kill_sb,
  5. };

点击(此处)折叠或打开

  1. struct vfsmount *kern_mount_data(struct file_system_type *type, void *data)
  2. {
  3.     return vfs_kern_mount(type, MS_KERNMOUNT, type->name, data); /* data=&init_pid_ns */
  4. }


点击(此处)折叠或打开

  1. void __init proc_root_init(void)
  2. {
  3.     int err;
  4.     /* 创建slab cache */
  5.     proc_init_inodecache();
  6.     /* 将proc fs注册到file_systems为链表头文件系统的链表里面
  7.         注意在register_filesystem函数中,会调用INIT_LIST_HEAD(&fs->fs_supers)初始化fs->fs_supers链表
  8.      */
  9.     err = register_filesystem(&proc_fs_type);
  10.     if (err)
  11.         return;

  12.     /* mount proc fs */
  13.    proc_mnt = kern_mount_data(&proc_fs_type, &init_pid_ns);
  1.     err = PTR_ERR(proc_mnt);
  2.     if (IS_ERR(proc_mnt)) {
  3.         unregister_filesystem(&proc_fs_type);
  4.         return;
  5.     }

  6.     proc_symlink("mounts", NULL, "self/mounts");

  7.     proc_net_init();

  8. #ifdef CONFIG_SYSVIPC
  9.     proc_mkdir("sysvipc", NULL);
  10. #endif
  11.     proc_mkdir("fs", NULL);
  12.     proc_mkdir("driver", NULL);
  13.     proc_mkdir("fs/nfsd", NULL); /* somewhere for the nfsd filesystem to be mounted */
  14. #if defined(CONFIG_SUN_OPENPROMFS) || defined(CONFIG_SUN_OPENPROMFS_MODULE)
  15.     /* just give it a mountpoint */
  16.     proc_mkdir("openprom", NULL);
  17. #endif
  18.     proc_tty_init();
  19. #ifdef CONFIG_PROC_DEVICETREE
  20.     proc_device_tree_init();
  21. #endif
  22.     proc_mkdir("bus", NULL);
  23.     proc_sys_init();
  24. }



阅读(828) | 评论(0) | 转发(0) |
0

上一篇:vfs_kern_mount

下一篇:VirtualBox 安装注意事项

给主人留下些什么吧!~~