一个最简单的aufs文件系统

转自:http://book.51cto.com/art/201401/427823.htm    《linux内核探秘》

2.3.1   一个最简单的文件系统aufs

我们先写一个最简单的文件系统,这个文件系统直接创建在内存中。它在内存中创建了两个目录和几个文件,用户可以通过ls命令显示目录和文件,但是无法创建目录和文件,也不能对文件进行读写操作。这样不涉及硬盘操作,大大简化了开始阶段需要考虑的问题,这个例子如代码清单2-5所示。

代码清单2-5   最简单文件系统aufs源代码

 
 
  1. #include <linux/module.h> 
  2. #include <linux/fs.h> 
  3. #include <linux/pagemap.h> 
  4. #include <linux/mount.h> 
  5. #include <linux/init.h> 
  6. #include <linux/namei.h> 
  7.  
  8. #define AUFS_MAGIC  0x64668735  
  9.  
  10. static struct vfsmount *aufs_mount;  
  11. static int aufs_mount_count;  
  12.  
  13. static struct inode *aufs_get_inode(struct super_block *sb, int mode, dev_t dev)  
  14. {  
  15.   struct inode *inode = new_inode(sb);  
  16.  
  17.   if (inode) {  
  18.        inode->i_mode = mode;  
  19.        inode->i_uid = current->fsuid;  
  20.        inode->i_gid = current->fsgid;  
  21.        inode->i_blksize = PAGE_CACHE_SIZE;  
  22.        inode->i_blocks = 0;  
  23.        inode->i_atime = inode->i_mtime = inode->i_ctime = CURRENT_TIME;  
  24.        switch (mode & S_IFMT) {  
  25.        default:  
  26.            init_special_inode(inode, mode, dev);  
  27.            break;  
  28.        case S_IFREG:  
  29.            printk("creat a  file \n");  
  30.            break;  
  31.        case S_IFDIR:  
  32.            inode->i_op = &simple_dir_inode_operations;  
  33.            inode->i_fop = &simple_dir_operations;  
  34.            printk("creat a dir file \n");  
  35.  
  36.            inode->i_nlink++;  
  37.            break;  
  38.        }  
  39.   }  
  40.   return inode;  
  41. }  
  42. /* SMP-safe */  
  43. static int aufs_mknod(struct inode *dir, struct dentry *dentry,  
  44.            int mode, dev_t dev)  
  45. {  
  46.   struct inode *inode;  
  47.   int error = -EPERM;  
  48.  
  49.   if (dentry->d_inode)  
  50.        return -EEXIST;  
  51.  
  52.   inode = aufs_get_inode(dir->i_sb, mode, dev);  
  53.   if (inode) {  
  54.        d_instantiate(dentry, inode);  
  55.        dget(dentry);  
  56.        error = 0;  
  57.   }  
  58.   return error;  
  59. }  
  60.  
  61. static int aufs_mkdir(struct inode *dir, struct dentry *dentry, int mode)  
  62. {  
  63.   int res;  
  64.  
  65.   res = aufs_mknod(dir, dentry, mode |S_IFDIR, 0);  
  66.   if (!res)  
  67.        dir->i_nlink++;  
  68.   return res;  
  69. }  
  70.  
  71. static int aufs_create(struct inode *dir, struct dentry *dentry, int mode)  
  72. {  
  73.   return aufs_mknod(dir, dentry, mode | S_IFREG, 0);  
  74. }  
  75.  
  76. static int aufs_fill_super(struct super_block *sb, void *data, int silent)  
  77. {  
  78.   static struct tree_descr debug_files[] = {{""}};  
  79.  
  80.   return simple_fill_super(sb, AUFS_MAGIC, debug_files);  
  81. }  
  82.  
  83. static struct super_block *aufs_get_sb(struct file_system_type *fs_type,  
  84.                 int flags, const char *dev_name,  
  85.                 void *data)  
  86. {  
  87.   return get_sb_single(fs_type, flags, data, aufs_fill_super);  
  88. }  
  89.  
  90. static struct file_system_type au_fs_type = {  
  91.   .owner =    THIS_MODULE,  
  92.   .name =     "aufs",  
  93.   .get_sb =   aufs_get_sb,  
  94.   .kill_sb =  kill_litter_super,  
  95. };  
  96.  
  97. static int aufs_create_by_name(const char *name, mode_t mode,  
  98.                  struct dentry *parent,  
  99.                  struct dentry **dentry)  
  100. {  
  101.   int error = 0;  
  102.  
  103.   /* If the parent is not specified, we create it in the root.  
  104.    * We need the root dentry to do this, which is in the super  
  105.    * block. A pointer to that is in the struct vfsmount that we  
  106.    * have around.  
  107.    */  
  108.   if (!parent ) {  
  109.        if (aufs_mount && aufs_mount->mnt_sb) {  
  110.            parent = aufs_mount->mnt_sb->s_root;  
  111.        }  
  112.   }  
  113.   if (!parent) {  
  114.        printk("Ah! can not find a parent!\n");  
  115.        return -EFAULT;  
  116.   }  
  117.  
  118.   *dentry = NULL;  
  119.   mutex_lock(&parent->d_inode->i_mutex);  
  120.   *dentry = lookup_one_len(name, parent, strlen(name));  
  121.   if (!IS_ERR(dentry)) {  
  122.        if ((mode & S_IFMT) == S_IFDIR)  
  123.             error = aufs_mkdir(parent->d_inode, *dentry, mode);  
  124.        else  
  125.             error = aufs_create(parent->d_inode, *dentry, mode);  
  126.   } else  
  127.        error = PTR_ERR(dentry);  
  128.   mutex_unlock(&parent->d_inode->i_mutex);  
  129.  
  130.   return error;  
  131. }  
  132.  
  133. struct dentry *aufs_create_file(const char *name, mode_t mode,  
  134.                   struct dentry *parent, void *data,  
  135.                   struct file_operations *fops)  
  136. {  
  137.   struct dentry *dentry = NULL;  
  138.   int error;  
  139.  
  140.   printk("aufs: creating file '%s'\n",name);  
  141.  
  142.   error = aufs_create_by_name(name, mode, parent, &dentry);  
  143.   if (error) {  
  144.        dentry = NULL;  
  145.        goto exit;  
  146.   }  
  147.   if (dentry->d_inode) {  
  148.        if (data)  
  149.             dentry->d_inode->u.generic_ip = data;  
  150.        if (fops)  
  151.             dentry->d_inode->i_fop = fops;  
  152.   }  
  153. exit:  
  154.   return dentry;  
  155. }  
  156.  
  157. struct dentry *aufs_create_dir(const char *name, struct dentry *parent)  
  158. {  
  159.   return aufs_create_file(name,  
  160.                   S_IFDIR | S_IRWXU | S_IRUGO | S_IXUGO,  
  161.                   parent, NULL, NULL);  
  162. }  
  163.  
  164. static int __init aufs_init(void)  
  165. {  
  166.   int retval;  
  167.        struct dentry *pslot;  
  168.  
  169.   retval = register_filesystem(&au_fs_type);  
  170.  
  171.   if (!retval) {  
  172.        aufs_mount = kern_mount(&au_fs_type);  
  173.        if (IS_ERR(aufs_mount)) {  
  174.            printk(KERN_ERR "aufs: could not mount!\n");  
  175.            unregister_filesystem(&au_fs_type);  
  176.            return retval;  
  177.        }  
  178.   }  
  179.  
  180.   pslot = aufs_create_dir("woman star",NULL);  
  181.   aufs_create_file("lbb", S_IFREG | S_IRUGO, pslot, NULL, NULL);  
  182.   aufs_create_file("fbb", S_IFREG | S_IRUGO, pslot, NULL, NULL);  
  183.   aufs_create_file("ljl", S_IFREG | S_IRUGO, pslot, NULL, NULL);  
  184.  
  185.   pslot = aufs_create_dir("man star",NULL);  
  186.   aufs_create_file("ldh", S_IFREG | S_IRUGO, pslot, NULL, NULL);  
  187.   aufs_create_file("lcw", S_IFREG | S_IRUGO, pslot, NULL, NULL);  
  188.   aufs_create_file("jw", S_IFREG | S_IRUGO, pslot, NULL, NULL);  
  189.  
  190.   return retval;  
  191. }  
  192. static void __exit aufs_exit(void)  
  193. {  
  194.   simple_release_fs(&aufs_mount, &aufs_mount_count);  
  195.   unregister_filesystem(&au_fs_type);  
  196. }  
  197.  
  198. module_init(aufs_init);  
  199. module_exit(aufs_exit);  
  200. MODULE_LICENSE("GPL");  
  201. MODULE_DESCRIPTION("This is a simple module");  
  202. MODULE_VERSION("Ver 0.1"); 

整个程序只有两百多行,即使对文件系统一点不懂也能了解大概意思。这个例子不包括文件读写等内容,目的只是说明文件系统内dentry、inode、super_block等几个重要概念。

程序编译后,我们通过insmod 命令加载模块,然后执行如下操作。

1)在根目录下创建一个目录:

 
 
  1. mkdir au 

2)挂载文件系统:

 
 
  1. mount –t aufs none /au 

3)列出文件系统的内容:

 
 
  1. ls 

看到了什么?可以发现“woman star”和“man star”两个目录。然后到woman star目录再执行ls,目录下果然有lbb、fbb、ljl三个文件。这就是我们在代码中希望做到的事情。


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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值