]> git.neil.brown.name Git - LaFS.git/commitdiff
Change s_fs_info to point to root inode and fs
authorNeil Brown <neilb@nbeee.brown>
Mon, 19 Jul 2010 08:36:47 +0000 (18:36 +1000)
committerNeilBrown <neilb@suse.de>
Mon, 9 Aug 2010 01:58:12 +0000 (11:58 +1000)
We create a new data structure containing the 'fs' and the root inode
of a filesystem, and store this in the superblock.
This allows each access to that root in iget, which previously was
impossible in general.

Signed-off-by: NeilBrown <neilb@suse.de>
inode.c
lafs.h
roll.c
snapshot.c
super.c

diff --git a/inode.c b/inode.c
index 47412793fb0b0b7820d25c8c2a8a80e0ded24bda..89722e480a2ee191d5112cd9b450409b0718cb39 100644 (file)
--- a/inode.c
+++ b/inode.c
@@ -67,18 +67,13 @@ lafs_iget(struct super_block *sb, ino_t inum, int async)
        struct inode *ino = NULL;
        struct datablock *b = NULL;
        struct inode *inodefile;
+       struct sb_key *k;
        int err = 0;
 
        BUG_ON(inum == NO_INO);
 
-       if (sb->s_root)
-               inodefile = LAFSI(sb->s_root->d_inode)->filesys;
-       else {
-               /* FIXME always use this branch?
-                * FIXME is this OK for all sub-filesystems?
-                */
-               inodefile = fs_from_sb(sb)->ss[0].root;
-       }
+       k = sb->s_fs_info;
+       inodefile = k->root;
 
        if (async) {
                /* We cannot afford to block on 'freeing_inode'
diff --git a/lafs.h b/lafs.h
index 9f6249ec44d34d639a7a057ae247368c4bfcba7c..13973252cf6b9147b2b7468e6fc1278cba6b1f16 100644 (file)
--- a/lafs.h
+++ b/lafs.h
@@ -331,10 +331,16 @@ static inline u64 encode_time(struct timespec *ts)
        return t | tn;
 }
 
+/* s_fs_info points to an allocated sb_key structure */
+struct sb_key {
+       struct inode *root;
+       struct fs *fs;
+};
+
 static inline struct fs *fs_from_sb(struct super_block *sb)
 {
-       struct fs *fs = sb->s_fs_info;
-       return fs;
+       struct sb_key *k = sb->s_fs_info;
+       return k->fs;
 }
 
 static inline struct fs *fs_from_inode(struct inode *ino)
diff --git a/roll.c b/roll.c
index ecb54e4c14944c2fd3612440d14be7a5044b7298..fbdf2fe120fb8ec97a99869e1c1f62d09345c806 100644 (file)
--- a/roll.c
+++ b/roll.c
@@ -552,9 +552,13 @@ lafs_mount(struct fs *fs)
        struct dentry *de;
        int err;
        int d;
+       struct sb_key *k = kmalloc(sizeof(*k), GFP_KERNEL);
 
        fs->rolled = 0;
        fs->ss[0].root = root = iget_locked(fs->prime_sb, 0);
+       k->root = root;
+       k->fs = fs;
+       fs->prime_sb->s_fs_info = k;
 
        err = -ENOMEM;
        b = lafs_get_block(root, 0, NULL, GFP_KERNEL, MKREF(mount));
index 920455751ecd558db3cd108ba05b273cdbcb7f68..07a53d74ec2c9cf6b1ab524c694b5f4e93abff72 100644 (file)
@@ -9,6 +9,7 @@
 #include       "lafs.h"
 #include       <linux/namei.h>
 #include       <linux/crc32.h>
+#include       <linux/slab.h>
 
 /*
  * Mounting a snapshot is very different from mounting a new
@@ -103,6 +104,7 @@ lafs_snap_get_sb(struct file_system_type *fstype,
        for (s = 1; s < fs->maxsnapshot; s++) {
                struct datablock *b;
                struct inode *rootdir;
+               struct sb_key *k;
                if (fs->ss[s].root_addr == 0)
                        continue;
                if (fs->ss[s].root) {
@@ -126,9 +128,12 @@ lafs_snap_get_sb(struct file_system_type *fstype,
                if (IS_ERR(sb))
                        return PTR_ERR(sb);
                sb->s_flags = flags | MS_RDONLY;
-               sb->s_fs_info = fs;
-               /* FIXME Inc refcount here?? */
                fs->ss[s].root = iget_locked(sb, 1);
+               k = kmalloc(sizeof(*k), GFP_KERNEL);
+               /* FIXME Inc refcount here?? */
+               k->fs = fs;
+               k->root = fs->ss[s].root;
+               sb->s_fs_info = k;
                b = lafs_get_block(fs->ss[s].root, 0, NULL, GFP_KERNEL,
                                   MKREF(snap));
                b->b.physaddr = fs->ss[s].root_addr;
@@ -178,6 +183,7 @@ static void lafs_snap_kill_sb(struct super_block *sb)
 
        printk("Generic_shutdown_super being called....\n");
        generic_shutdown_super(sb);
+       kfree(sb->s_fs_info);
        printk("Generic_shutdown_super called\n");
        deactivate_super(fs->prime_sb);
 }
diff --git a/super.c b/super.c
index 5e3ecd51a12b614c80f8571ef7a564422738c0ed..1bdd737dee1f057031eb7ec2624654caab31aa73 100644 (file)
--- a/super.c
+++ b/super.c
@@ -555,7 +555,6 @@ lafs_load(struct fs *fs, struct options *op, int newest)
        fs->prime_sb = sget(&lafs_fs_type, NULL, set_anon_super, NULL);
        if (!fs->prime_sb)
                goto abort;
-       fs->prime_sb->s_fs_info = fs;
        fs->prime_sb->s_blocksize = 1 << op->blockbits;
        fs->prime_sb->s_blocksize_bits = op->blockbits;
        fs->prime_sb->s_op = &lafs_sops;
@@ -707,6 +706,7 @@ static void lafs_kill_sb(struct super_block *sb)
        kfree(fs->devs);
        lafs_segtrack_free(fs->segtrack);
        kfree(fs->scan.free_usages);
+       kfree(fs->prime_sb->s_fs_info);
        kfree(fs);
 }