From: Neil Brown Date: Mon, 19 Jul 2010 08:36:47 +0000 (+1000) Subject: Change s_fs_info to point to root inode and fs X-Git-Url: http://git.neil.brown.name/?a=commitdiff_plain;h=43f6d8c7a67a49fb563da3bf53e146a5aea89596;p=LaFS.git Change s_fs_info to point to root inode and fs 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 --- diff --git a/inode.c b/inode.c index 4741279..89722e4 100644 --- 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 9f6249e..1397325 100644 --- 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 ecb54e4..fbdf2fe 100644 --- 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)); diff --git a/snapshot.c b/snapshot.c index 9204557..07a53d7 100644 --- a/snapshot.c +++ b/snapshot.c @@ -9,6 +9,7 @@ #include "lafs.h" #include #include +#include /* * 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 5e3ecd5..1bdd737 100644 --- 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); }