文件系统学习3 注册和加载 以及路径解析

来源:互联网 发布:mac香港专柜价格 编辑:程序博客网 时间:2024/06/10 01:59

文件系统注册

module_init(init_ext3_fs)    =>init_ext3_xattr();    =>init_inodecache();    =>register_filesystem(&ext3_fs_type);//如果在链表则返回,否则加入链表        static struct file_system_type ext3_fs_type = {            .owner      = THIS_MODULE,            .name       = "ext3",            .get_sb     = ext3_get_sb,            .kill_sb    = kill_block_super,            .fs_flags   = FS_REQUIRES_DEV,        };

加载,共有两个路径,都需要解析

sys_mount    =>retval = do_mount((char *)dev_page, dir_page, (char *)type_page, flags, (void *)data_page);        =>retval = path_lookup(dir_name, LOOKUP_FOLLOW, &nd);            =>do_path_lookup(AT_FDCWD, name, flags, nd);//加载的路径解析                =>if (*name=='/')                    ==>nd->mnt = mntget(fs->rootmnt);                    ==>nd->dentry = dget(fs->root);                =>else if (dfd == AT_FDCWD)                    ==>nd->mnt = mntget(fs->pwdmnt);                    ==>nd->dentry = dget(fs->pwd);                =>retval = path_walk(name, nd);                         }        =>retval = do_new_mount(&nd, type_page, flags, mnt_flags, dev_name, data_page);            =>struct vfsmount *mnt = do_kern_mount(type, flags, name, data);                =>struct file_system_type *type = get_fs_type(fstype);                =>struct vfsmount *mnt = vfs_kern_mount(type, flags, name, data);//3大功能 分配mnt;分配sb(如果没有分配的话);填充mnt基本信息                    =>mnt = alloc_vfsmnt(name);//第一功能                    =>error = type->get_sb(type, flags, name, data, mnt);//Super.c (c:\linux\linux-2.6.23\fs\ext2): .get_sb     = ext2_get_sb,//第二功能                        =>ext2_get_sb                            =>get_sb_bdev(fs_type, flags, dev_name, data, ext2_fill_super, mnt);                                =>bdev = open_bdev_excl(dev_name, flags, fs_type);                                    =>struct block_device *bdev = lookup_bdev(path);                                        =>error = path_lookup(path, LOOKUP_FOLLOW, &nd);                                            =>do_path_lookup(AT_FDCWD, name, flags, nd);//设备节点路径解析                                        =>inode = nd.dentry->d_inode;                                        =>bdev = bd_acquire(inode);                                =>s = sget(fs_type, test_bdev_super, set_bdev_super, bdev);                                =>if (s->s_root)                                    close_bdev_excl(bdev);//如果已经有super block,那么不需要重新申请和填充                                =>else                                    sb_set_blocksize(s, block_size(bdev));                                    error = fill_super(s, data, flags & MS_SILENT ? 1 : 0);                    =>mnt->mnt_mountpoint = mnt->mnt_root;//第三功能                    mnt->mnt_parent = mnt;            =>do_add_mount(mnt, nd, mnt_flags, NULL);//将mnt放到对应的一坨各种链表里面                =>while (d_mountpoint(nd->dentry) && follow_down(&nd->mnt, &nd->dentry));//抽丝剥茧,找到堆叠的最底层的dentry,详见《mount过程分析之七(do_add_mount)》                =>err = graft_tree(newmnt, nd))//加入链表

全路径查找是核心

static int fastcall path_walk(const char * name, struct nameidata *nd)    =>link_path_walk(name, nd);        =>result = __link_path_walk(name, nd);            =>inode = nd->dentry->d_inode;            =>for(;;) //每一次循环,剥离一层目录                ==>do_lookup(nd, &this, &next);                    =>struct dentry *dentry = __d_lookup(nd->dentry, name);                    =>dentry = real_lookup(nd->dentry, name, nd);                        =>result = d_lookup(parent, name);                            =>struct hlist_head *head = d_hash(parent,hash);                            =>hlist_for_each_entry_rcu(dentry, node, head, d_hash)//命中哈希后,在哈希的链表里面遍历                                ==>found = dentry;//找到则返回                        =>if (!result)//如果缓存没有找到                            ==>result = dir->i_op->lookup(dir, dentry, nd);                                =>ext2_lookup                                    =>ino = ext2_inode_by_name(dir, dentry);                                        =>struct ext2_dir_entry_2 * de = ext2_find_entry (dir, dentry, &page);                ==>if ((lookup_flags & LOOKUP_FOLLOW) && inode && inode->i_op && inode->i_op->follow_link)                    ====>err = do_follow_link(&next, nd);                    ====>inode = nd->dentry->d_inode;                ==>else                    ====>path_to_nameidata(&next, nd);                        =>nd->mnt = path->mnt;                        nd->dentry = path->dentry;

文件系统错误修复实例(1)
http://blog.csdn.net/ChuiGeDaQiQiu/article/details/24138875

卸载文件系统失败的时候可以通过fuser检查和杀死访问磁盘的进程

fuser命令详解(原创)
http://czmmiao.iteye.com/blog/1733722

e2fsprogs编译问题
http://blog.csdn.net/sanwenyublog/article/details/52817796

mount过程分析之六——挂载关系(图解)
http://blog.csdn.net/ZR_Lang/article/details/40343899

mount过程分析之七(do_add_mount)
http://blog.csdn.net/ZR_Lang/article/details/40325241