From: Neil Brown Date: Mon, 19 Jul 2010 04:57:20 +0000 (+1000) Subject: Use anon super for prime_sb X-Git-Url: http://git.neil.brown.name/?a=commitdiff_plain;h=effb90a90cac0661320686cd10887ce697571e60;p=LaFS.git Use anon super for prime_sb This is cleaner. also clean up failure path for lafs_load Signed-off-by: NeilBrown --- diff --git a/super.c b/super.c index 9b6119f..59a2c08 100644 --- a/super.c +++ b/super.c @@ -513,13 +513,9 @@ lafs_load(struct options *op, int newest) err = lafs_segtrack_init(fs->segtrack); fs->ss = kzalloc(sizeof(struct snapshot)*fs->maxsnapshot, GFP_KERNEL); - if (!fs->ss || !fs->scan.free_usages || err) { - kfree(fs->ss); - kfree(fs->scan.free_usages); - lafs_segtrack_free(fs->segtrack); - kfree(fs); - return NULL; - } + if (!fs->ss || !fs->scan.free_usages || err) + goto abort; + fs->checkpointcluster = le64_to_cpu(st->checkpointcluster); for (i = 0; i < fs->maxsnapshot; i++) { fs->ss[i].root_addr = @@ -562,12 +558,18 @@ lafs_load(struct options *op, int newest) */ fs->devs = kzalloc(sizeof(struct fs_dev)*fs->devices, GFP_KERNEL); - if (!fs->devs) { - /* FIXME free more stuff */ - kfree(fs->ss); - kfree(fs); - return NULL; - } + if (!fs->devs) + goto abort; + + 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; + fs->prime_sb->s_export_op = &lafs_export_ops; + fs->prime_sb->s_root = NULL; for (i = 0; i < fs->devices; i++) { struct fs_dev *dv = &fs->devs[i]; @@ -578,10 +580,7 @@ lafs_load(struct options *op, int newest) dv->sb->s_fs_info = fs; dv->sb->s_blocksize = 1 << op->blockbits; dv->sb->s_blocksize_bits = op->blockbits; - if (fs->prime_sb == NULL) - fs->prime_sb = dv->sb; - else - up_write(&dv->sb->s_umount); + up_write(&dv->sb->s_umount); dv->devblk = de->devblock; de->devblock = NULL; @@ -629,6 +628,14 @@ lafs_load(struct options *op, int newest) dv->sb->s_root = NULL; } return fs; + +abort: + kfree(fs->scan.free_usages); + lafs_segtrack_free(fs->segtrack); + kfree(fs->devs); + kfree(fs->ss); + kfree(fs); + return NULL; } static int show_orphans(struct fs *fs) @@ -646,9 +653,9 @@ static int show_orphans(struct fs *fs) return 1; /* meaningless, but makes it easy to add to wait_event below */ } -static void -lafs_release(struct fs *fs) +static void lafs_kill_sb(struct super_block *sb) { + struct fs *fs = sb->s_fs_info; /* Release the 'struct fs' */ int i; @@ -673,6 +680,8 @@ lafs_release(struct fs *fs) fs->scan.done == 1 && fs->cleaner.active == 0); + kill_anon_super(fs->prime_sb); + for (i = 0; i < fs->devices; i++) { struct fs_dev *dv = &fs->devs[i]; kfree(dv->devblk); @@ -867,7 +876,11 @@ lafs_get_sb(struct file_system_type *fs_type, if (err == 0) err = lafs_start_cleaner(fs); if (err) - lafs_release(fs); + deactivate_locked_super(fs->prime_sb); + else { + fs->prime_sb->s_flags |= MS_ACTIVE; + simple_set_mnt(mnt, fs->prime_sb); + } /* And there you have it. Filesystem all mounted, root dir found, * metadata files initialised, all pigs fed, and ready to fly!!! */ @@ -888,19 +901,7 @@ out: } kfree(op.devlist); } - if (err) - return err; - else { - simple_set_mnt(mnt, fs->prime_sb); - return 0; - } -} - -static void lafs_kill_sb(struct super_block *sb) -{ - struct fs *fs = sb->s_fs_info; - - lafs_release(fs); + return err; } struct file_system_type lafs_fs_type = {