From: NeilBrown Date: Mon, 7 Mar 2011 06:00:03 +0000 (+1100) Subject: Stop creating a super_block for each subset filesystem. X-Git-Url: http://git.neil.brown.name/?a=commitdiff_plain;h=957e040dd6239a574929c35c4bcbe2dbc805fa45;p=LaFS.git Stop creating a super_block for each subset filesystem. Rather, we use just one super_block and differentiate based on ->filesys. Signed-off-by: NeilBrown --- diff --git a/inode.c b/inode.c index 69df4d0..04b2188 100644 --- a/inode.c +++ b/inode.c @@ -87,7 +87,7 @@ lafs_iget(struct inode *fsys, ino_t inum, int async) struct datablock *b = NULL; struct ikey ik = { .inum = inum, .fsys = fsys, }; int err = 0; - struct super_block *sb = fsys->i_private; + struct super_block *sb = fsys->i_sb; if (async) { /* We cannot afford to block on 'freeing_inode' @@ -234,7 +234,6 @@ lafs_iget_fs(struct fs *fs, int fsnum, int inum, int async) * subordinate filesystem */ struct inode *filesys; - struct super_block *sb2; filesys = lafs_iget(fs->ss[0].root, fsnum, async); if (IS_ERR(filesys)) @@ -243,17 +242,7 @@ lafs_iget_fs(struct fs *fs, int fsnum, int inum, int async) iput(filesys); return ERR_PTR(-ENOENT); } - /* FIXME can get_subset_sb be async at all?? */ - sb2 = lafs_get_subset_sb(filesys); - if (IS_ERR(sb2)) { - iput(filesys); - return ERR_PTR(PTR_ERR(sb2)); - } rv = lafs_iget(filesys, inum, async); - if (IS_ERR(rv)) - deactivate_locked_super(sb2); - else - up_write(&sb2->s_umount); } else if (inum) { rv = lafs_iget(fs->ss[0].root, inum, async); if (!IS_ERR(rv)) diff --git a/lafs.h b/lafs.h index 70a25d0..cbdb1b8 100644 --- a/lafs.h +++ b/lafs.h @@ -367,12 +367,6 @@ static inline struct fs *fs_from_sb(struct super_block *sb) return k->fs; } -static inline struct inode *ino_from_sb(struct super_block *sb) -{ - struct sb_key *k = sb->s_fs_info; - return k->root; -} - static inline struct fs *fs_from_inode(struct inode *ino) { return fs_from_sb(ino->i_sb); @@ -707,7 +701,6 @@ int lafs_cluster_empty(struct fs *fs, int cnum); /* super.c */ int lafs_write_state(struct fs *fs); void lafs_destroy_inode(struct inode *inode); -struct super_block *lafs_get_subset_sb(struct inode *ino); /* checkpoint.c */ void lafs_checkpoint_lock(struct fs *fs); diff --git a/roll.c b/roll.c index 6ffe3e5..b1079b4 100644 --- a/roll.c +++ b/roll.c @@ -297,7 +297,6 @@ roll_mini(struct fs *fs, int fsnum, int inum, int trunc, fsinode = inode; inode = lafs_iget_fs(fs, inum, bnum, SYNC); if (IS_ERR(inode)) { - struct super_block *sb; err = PTR_ERR(inode); if (err != -ENOENT || offset != 0) { lafs_iput_fs(fsinode); @@ -306,9 +305,7 @@ roll_mini(struct fs *fs, int fsnum, int inum, int trunc, db = lafs_get_block(fsinode, bnum, NULL, GFP_KERNEL, MKREF(roll)); - sb = lafs_get_subset_sb(fsinode); lafs_inode_inuse(fs, fsinode, bnum); - deactivate_super(sb); lafs_iput_fs(fsinode); if (!db) db = ERR_PTR(-ENOMEM); @@ -797,8 +794,6 @@ lafs_mount(struct fs *fs) k->root = rootino; LAFSI(rootino)->filesys = rootino; - rootino->i_private = fs->prime_sb; - err = -ENOMEM; if (!rootino) goto err; diff --git a/snapshot.c b/snapshot.c index 23cf5a3..661f689 100644 --- a/snapshot.c +++ b/snapshot.c @@ -168,7 +168,6 @@ lafs_snap_get_sb(struct file_system_type *fstype, atomic_inc(&fs->prime_sb->s_active); rootino = iget_locked(sb, 0); - rootino->i_private = sb; fs->ss[s].root = sk->k.root = rootino; LAFSI(rootino)->filesys = rootino; b = lafs_get_block(rootino, 0, NULL, GFP_KERNEL, diff --git a/super.c b/super.c index 6156c96..591f2c2 100644 --- a/super.c +++ b/super.c @@ -987,99 +987,56 @@ out: return err; } -static int test_subset(struct super_block *sb, void *data) -{ - struct sb_key *ptn = data; - struct sb_key *k = sb->s_fs_info; - - return ptn->fs == k->fs && ptn->root == k->root; -} - -static int set_subset(struct super_block *sb, void *data) -{ - sb->s_fs_info = data; - set_anon_super(sb, NULL); - return 0; -} - -static struct file_system_type lafs_subset_fs_type; -struct super_block *lafs_get_subset_sb(struct inode *ino) +static struct dentry *lafs_get_subset_root(struct inode *ino) { /* ino must be a TypeInodeFile inode in the prime filesystem. */ struct fs *fs = fs_from_inode(ino); struct super_block *sb; - struct sb_key *k = kmalloc(sizeof(*k), GFP_KERNEL); - - if (!k) - return ERR_PTR(-ENOMEM); - - k->fs = fs; - k->root = ino; - sb = sget(&lafs_subset_fs_type, test_subset, set_subset, k); - if (IS_ERR(sb)) { - kfree(k); - } else if (sb->s_root) { - /* already allocated */ - kfree(k); - } else { - struct inode *rootdir, *imapfile; - int err = 0; - - ino->i_private = sb; - - 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(ino, 2, SYNC); - if (IS_ERR(rootdir) && PTR_ERR(rootdir) == -ENOENT) { - rootdir = lafs_new_inode(fs, ino, NULL, - TypeDir, 2, 0755, NULL); - /* FIXME could the inode get written before we set - * the link count ??*/ - rootdir->i_nlink = 2; - } - if (IS_ERR(rootdir)) - err = PTR_ERR(rootdir); - else { - sb->s_root = d_alloc_root(rootdir); - imapfile = lafs_iget(ino, 1, SYNC); - if (IS_ERR(imapfile) && PTR_ERR(imapfile) == -ENOENT) - imapfile = lafs_new_inode(fs, ino, NULL, - TypeInodeMap, 1, 0, NULL); - - if (IS_ERR(imapfile)) - err = PTR_ERR(imapfile); - else - iput(imapfile); - } - - if (!err) { - struct inode *atime = lafs_iget(ino, 3, SYNC); - if (!IS_ERR(atime)) { - if (LAFSI(atime)->type != TypeAccessTime) { - iput(atime); - err = -EINVAL; - } else - LAFSI(ino)->md.fs.accesstime = atime; - } else if (PTR_ERR(atime) != -ENOENT) - err = PTR_ERR(ino); - } + int err = 0; + struct inode *rootdir, *imapfile; + struct dentry *root; + + sb = fs->prime_sb; + + rootdir = lafs_iget(ino, 2, SYNC); + if (IS_ERR(rootdir) && PTR_ERR(rootdir) == -ENOENT) { + rootdir = lafs_new_inode(fs, ino, NULL, + TypeDir, 2, 0755, NULL); + /* FIXME could the inode get written before we set + * the link count ??*/ + rootdir->i_nlink = 2; + } + if (IS_ERR(rootdir)) + err = PTR_ERR(rootdir); + else { + root = d_alloc_root(rootdir); + imapfile = lafs_iget(ino, 1, SYNC); + if (IS_ERR(imapfile) && PTR_ERR(imapfile) == -ENOENT) + imapfile = lafs_new_inode(fs, ino, NULL, + TypeInodeMap, 1, 0, NULL); + + if (IS_ERR(imapfile)) + err = PTR_ERR(imapfile); + else + iput(imapfile); + } - if (!err) { - sb->s_op = fs->prime_sb->s_op; - sb->s_flags |= MS_ACTIVE; - atomic_inc(&fs->prime_sb->s_active); - igrab(ino); - } else { - deactivate_locked_super(sb); - sb = ERR_PTR(err); - } + if (!err) { + struct inode *atime = lafs_iget(ino, 3, SYNC); + if (!IS_ERR(atime)) { + if (LAFSI(atime)->type != TypeAccessTime) { + iput(atime); + err = -EINVAL; + } else + LAFSI(ino)->md.fs.accesstime = atime; + } else if (PTR_ERR(atime) != -ENOENT) + err = PTR_ERR(ino); } - return sb; + if (err) { + dput(root); + return ERR_PTR(err); + } else + return root; } static int @@ -1104,6 +1061,7 @@ lafs_get_subset(struct file_system_type *fs_type, struct super_block *sb; struct inode *ino; struct fs *fs; + struct dentry *root; err = path_lookup(dev_name, LOOKUP_FOLLOW, &nd); if (err) @@ -1113,12 +1071,14 @@ lafs_get_subset(struct file_system_type *fs_type, if (sb->s_type != &lafs_fs_type && sb->s_type != &lafs_snap_fs_type) goto out; + /* FIXME test not a subset filesystem */ ino = nd.path.dentry->d_inode; if (LAFSI(ino)->type != TypeInodeFile && LAFSI(ino)->type != TypeDir) goto out; fs = fs_from_sb(sb); mutex_lock(&ino->i_mutex); + err = 0; if (LAFSI(ino)->type == TypeDir) { struct datablock *inodb; /* maybe convert this to TypeInodeFile */ @@ -1180,15 +1140,17 @@ lafs_get_subset(struct file_system_type *fs_type, if (err) goto out_unlock; } - err = 0; /* We have a TypeInodeFile so we can make a superblock */ - sb = lafs_get_subset_sb(ino); + root = lafs_get_subset_root(ino); iput(ino); - if (IS_ERR(sb)) - err = PTR_ERR(sb); - else - simple_set_mnt(mnt, sb); + if (IS_ERR(root)) + err = PTR_ERR(root); + else { + mnt->mnt_sb = fs->prime_sb; + atomic_inc(&mnt->mnt_sb->s_active); + mnt->mnt_root = root; + } out_unlock: mutex_unlock(&ino->i_mutex); out: @@ -1197,19 +1159,6 @@ out_noput: return err; } -static void lafs_kill_subset(struct super_block *sb) -{ - struct sb_key *k = sb->s_fs_info; - if (LAFSI(k->root)->md.fs.accesstime) { - iput(LAFSI(k->root)->md.fs.accesstime); - LAFSI(k->root)->md.fs.accesstime = NULL; - } - kill_anon_super(sb); - iput(k->root); - deactivate_super(k->fs->prime_sb); - kfree(k); -} - const struct file_operations lafs_subset_file_operations = { }; @@ -1229,7 +1178,6 @@ static struct file_system_type lafs_subset_fs_type = { .owner = THIS_MODULE, .name = "lafs_subset", .get_sb = lafs_get_subset, - .kill_sb = lafs_kill_subset, }; static int __init lafs_init(void)