Chinaunix首页 | 论坛 | 博客
  • 博客访问: 2112775
  • 博文数量: 438
  • 博客积分: 3871
  • 博客等级: 中校
  • 技术积分: 6075
  • 用 户 组: 普通用户
  • 注册时间: 2011-09-10 00:11
个人简介

邮箱: wangcong02345@163.com

文章分类

全部博文(438)

文章存档

2017年(15)

2016年(119)

2015年(91)

2014年(62)

2013年(56)

2012年(79)

2011年(16)

分类: LINUX

2013-09-10 11:15:49

一. 临时文件系统的挂载过程
系统开始时先挂载了一个临时的文件系统,通过这个临时的文件系统
  1. init/main.c
  2. start_kernel
  3. {
  4.     vfs_caches_init(totalram_pages);  ;在fs/dcache.c:创建一个虚拟的文件系统
  5.         --> mnt_init                  ;在fs/namespace.c中  
  6.             --> init_rootfs           ;1.在fs/ramfs/inode.c中
  7.             --> init_mount_tree();    ;2.在fs/namespace.c中
  8. }
1.在fs/ramfs/inode.c中
  1. int __init init_rootfs(void)
  2. {
  3.     bdi_init(&ramfs_backing_dev_info);       //初始化ramfs_backing_dev_info结构体
  4.     register_filesystem(&rootfs_fs_type);    //1.1注册rootfs_fs_type,
  5. }                                               即把rootfs_fs_type添加到全局变量中

  6. static struct backing_dev_info ramfs_backing_dev_info = {
  7.     .name        = "ramfs",
  8.     .ra_pages    = 0,    /* No readahead */
  9.     .capabilities    = BDI_CAP_NO_ACCT_AND_WRITEBACK |
  10.              BDI_CAP_MAP_DIRECT | BDI_CAP_MAP_COPY |
  11.              BDI_CAP_READ_MAP | BDI_CAP_WRITE_MAP | BDI_CAP_EXEC_MAP,
  12. };

  13. static struct file_system_type rootfs_fs_type = {
  14.     .name        = "rootfs",
  15.     .mount        = rootfs_mount,
  16.     .kill_sb    = kill_litter_super,
  17. };
1.1全局变量file_systems链表中将参数fs添加进来
  1. int register_filesystem(struct file_system_type * fs)
  2. {

  3.     struct file_system_type ** p;
  4.     INIT_LIST_HEAD(&fs->fs_supers);
  5.     write_lock(&file_systems_lock);
  6.     p = find_filesystem(fs->name, strlen(fs->name)); //1.1.1在全局变量file_system中查找 
  7.     if (*p)              //如果在全局变量中能够找到,*p!=NULL说明这个文件系统己经注册过了
  8.         res = -EBUSY;
  9.     else                 //如果在全局变量中不能找到,*p==NULL,说明这个文件系统没有注册可以使用
  10.         *p = fs;         //使得file_systems.next=fs,链表中增加一项
  11.     write_unlock(&file_systems_lock);
  12.     return res;
  13. }
1.1.1在全局变量文件系统类型的链表中查找有没有名字等于参数name的文件系统类型
  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. }
2.在fs/namespace.c中
  1. static void __init init_mount_tree(void)
  2. {
  3.     struct vfsmount *mnt;
  4.     struct mnt_namespace *ns;
  5.     struct path root;

  6.     mnt = do_kern_mount("rootfs", 0, "rootfs", NULL);   //2.1
  7.     ns = create_mnt_ns(mnt);                            //为新的文件系统创建namespace
  8.     init_task.nsproxy->mnt_ns = ns;
  9.     get_mnt_ns(ns);
  10.     root.mnt = ns->root;
  11.     root.dentry = ns->root->mnt_root;
  12.     set_fs_pwd(current->fs, &root);                   //将进程0的当前路径设为rootfs的root
  13.     set_fs_root(current->fs, &root);                  //将进程0的fs设为rootfs的root
  14. }
2.1在fs/namespace.c中
  1. struct vfsmount * do_kern_mount(const char *fstype, int flags, const char *name, void *data)
  2. {
  3.     //从全局变量file_systems中找出刚刚注册的"rootfs"的地址
  4.     struct file_system_type *type = get_fs_type(fstype);
  5.     struct vfsmount *mnt;
  6.     if (!type)
  7.         return ERR_PTR(-ENODEV);
  8.     mnt = vfs_kern_mount(type, flags, name, data);   //2.1.1
  9.     put_filesystem(type);                  //空函数
  10.     return mnt;
  11. }
2.1.1 rootfs的mount过程
在fs/namespace.c中
  1. struct vfsmount * vfs_kern_mount(struct file_system_type *type, int flags, const char *name, void *data)
  2. {
  3.     struct vfsmount *mnt;
  4.     struct dentry *root;

  5.     if (!type)
  6.         return ERR_PTR(-ENODEV);
  7.     mnt = alloc_vfsmnt(name);                  //申请并初始化vfsmount结构体
  8.     //这儿flags==0
  9.     if (flags & MS_KERNMOUNT)
  10.         mnt->mnt_flags = MNT_INTERNAL;
  11.     root = mount_fs(type, flags, name, data)//2.1.2
  12.     mnt->mnt_root = root;
  13.     mnt->mnt_sb = root->d_sb;
  14.     mnt->mnt_mountpoint = mnt->mnt_root;
  15.     mnt->mnt_parent = mnt;
  16.     return mnt;
  17. }
2.1.2调用具体文件系统的mount
在fs/super.c中
  1. struct dentry * mount_fs(struct file_system_type *type, int flags, const char *name, void *data)
  2. {
  3.     struct dentry *root;
  4.     struct super_block *sb;
  5.     //file_system_type rootfs_fs_type 中定义.mount = rootfs_mount,
  6.     root = type->mount(type, flags, name, data);    //调用具体文件系统的mount
  7.     sb = root->d_sb;
  8.     sb->s_flags |= MS_BORN;
  9.     up_write(&sb->s_umount);  
  10.     return root;
  11. }
2.1.3fs/ramfs/inode.c中
  1. static struct dentry *rootfs_mount(struct file_system_type *fs_type,
  2.     int flags, const char *dev_name, void *data)
  3. {
  4.     return mount_nodev(fs_type, flags|MS_NOUSER, data, ramfs_fill_super);
  5. }
2.1.4 在fs/super.c中
  1. struct dentry *mount_nodev(struct file_system_type *fs_type, int flags, void *data,
  2.     int (*fill_super)(struct super_block *, void *, int))
  3. {
  4.     struct super_block *s = sget(fs_type, NULL, set_anon_super, NULL);   //2.1.5
  5.     s->s_flags = flags;
  6.     error = fill_super(s, data, flags & MS_SILENT ? 1 : 0);   //2.1.6调用ramfs_fill_super,初始化super_block和root
  7.     s->s_flags |= MS_ACTIVE;
  8.     return dget(s->s_root);         //获取在fill_super中初始化好的root
  9. }
2.1.5 分配一个super_block并做初初化
  1. struct super_block *sget(struct file_system_type *type,
  2.             int (*test)(struct super_block *,void *),
  3.             int (*set)(struct super_block *,void *),
  4.             void *data)
  5. {
  6.     struct super_block *s = NULL;
  7.     struct super_block *old;
  8.     int err;
  9. retry:
  10.     if (!s) {      
  11.         s = alloc_super(type);        //s是空的就需要分配一个super_block结构体
  12.         if (!s)
  13.             return ERR_PTR(-ENOMEM);
  14.         goto retry;
  15.     }

  16.     err = set(s, data);
  17.     s->s_type = type;
  18.     strlcpy(s->s_id, type->name, sizeof(s->s_id));
  19.     list_add_tail(&s->s_list, &super_blocks);
  20.     list_add(&s->s_instances, &type->fs_supers);
  21.     spin_unlock(&sb_lock);
  22.     get_filesystem(type);
  23.     return s;
  24. }
2.1.6 初始化super_block并初始化root
  1. int ramfs_fill_super(struct super_block *sb, void *data, int silent)
  2. {
  3.     struct ramfs_fs_info *fsi;
  4.     struct inode *inode = NULL;
  5.     struct dentry *root;
  6.     int err;

  7.     save_mount_options(sb, data);

  8.     fsi = kzalloc(sizeof(struct ramfs_fs_info), GFP_KERNEL);
  9.     sb->s_fs_info = fsi;

  10.     err = ramfs_parse_options(data, &fsi->mount_opts);

  11.     sb->s_maxbytes        = MAX_LFS_FILESIZE;
  12.     sb->s_blocksize        = PAGE_CACHE_SIZE;
  13.     sb->s_blocksize_bits    = PAGE_CACHE_SHIFT;
  14.     sb->s_magic        = RAMFS_MAGIC;
  15.     sb->s_op        = &ramfs_ops;
  16.     sb->s_time_gran        = 1;
  17.     //分配inode结构体并初始化inode->i_ino=1
  18.     inode = ramfs_get_inode(sb, NULL, S_IFDIR | fsi->mount_opts.mode, 0);
  19.     //初始化root的dentry结构体
  20.     root = d_alloc_root(inode);
  21.     sb->s_root = root;
  22.     return 0;
  23. }

二. 真正的文件系统的挂载过程


阅读(1613) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~