]> git.neil.brown.name Git - LaFS.git/commitdiff
Various fixes for lafs_get_subset
authorNeilBrown <neilb@suse.de>
Fri, 13 Aug 2010 06:14:27 +0000 (16:14 +1000)
committerNeilBrown <neilb@suse.de>
Fri, 13 Aug 2010 06:14:27 +0000 (16:14 +1000)
- make sure root directory is created if it doesn't exist
- also create inode usage map.
- hold a ref on the inode while the fs is mounted.
- free the sb_key at unmount.
- set s_bdi from the prime_sb

super.c

diff --git a/super.c b/super.c
index 7dabfd6034801e66bb578cc6b2277e8500763647..6c88d9ea317f5e3e9ee17d26919732127a8c9c77 100644 (file)
--- a/super.c
+++ b/super.c
@@ -1034,15 +1034,32 @@ lafs_get_subset(struct file_system_type *fs_type,
                /* already allocated */
                kfree(k);
        } else {
-               struct inode *rootdir;
+               struct inode *rootdir, *imapfile;
                err = 0;
+               igrab(ino);
                sb->s_blocksize = fs->blocksize;
                sb->s_blocksize_bits = fs->blocksize_bits;
+               sb->s_bdi = fs->prime_sb->s_bdi;
                sb->s_op = &lafs_sops;
                sb->s_export_op = &lafs_export_ops;
                sb->s_time_gran = 2;
                rootdir = lafs_iget(sb, 2, SYNC);
+               if (IS_ERR(rootdir) && PTR_ERR(rootdir) == -ENOENT) {
+                       rootdir = lafs_new_inode(fs, sb, NULL,
+                                                TypeDir, 2, 0755, NULL);
+                       /* FIXME could the inode get written before we set
+                        * the link count ??*/
+                       rootdir->i_nlink = 2;
+               }
                sb->s_root = d_alloc_root(rootdir);
+               imapfile = lafs_iget(sb, 1, SYNC);
+               if (IS_ERR(imapfile) && PTR_ERR(imapfile) == -ENOENT)
+                       imapfile = lafs_new_inode(fs, sb, NULL,
+                                                 TypeInodeMap, 1, 0, NULL);
+
+               if (!IS_ERR(imapfile))
+                       iput(imapfile);
+
                sb->s_op = fs->prime_sb->s_op;
                sb->s_flags |= MS_ACTIVE;
                atomic_inc(&fs->prime_sb->s_active);
@@ -1059,9 +1076,11 @@ out_noput:
 
 static void lafs_kill_subset(struct super_block *sb)
 {
-       struct fs *fs = fs_from_sb(sb);
+       struct sb_key *k = sb->s_fs_info;
        kill_anon_super(sb);
-       deactivate_super(fs->prime_sb);
+       iput(k->root);
+       deactivate_super(k->fs->prime_sb);
+       kfree(k);
 }
 
 struct file_system_type lafs_fs_type = {