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 =
*/
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];
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;
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)
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;
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);
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!!!
*/
}
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 = {