GFS: Don't free superblock until last kobject user is done
Hi,
This patch rearranges the sysfs interface to more closely match
GFS2, plus it adds an object release mechanism, as described in
kernel/Documentation/kobject.txt
diff --git a/gfs-kernel/src/gfs/ops_fstype.c b/gfs-kernel/src/gfs/ops_fstype.c
index 34d9fa4..7104a2d 100644
--- a/gfs-kernel/src/gfs/ops_fstype.c
+++ b/gfs-kernel/src/gfs/ops_fstype.c
@@ -682,12 +682,24 @@ static int fill_super(struct super_block *sb, void *data, int silent)
goto fail;
}
error = init_names(sdp, silent);
- if (error)
- goto fail;
+ if (error) {
+ /* In this case, we haven't initialized sysfs, so we have to
+ manually free the sdp. */
+ vfree(sdp);
+ sb->s_fs_info = NULL;
+ return error;
+ }
error = gfs_sys_fs_add(sdp);
+ /*
+ * If we hit an error here, gfs2_sys_fs_add will have called function
+ * kobject_put which causes the sysfs usage count to go to zero, which
+ * causes sysfs to call function gfs2_sbd_release, which frees sdp.
+ * Subsequent error paths here will call gfs_sys_fs_del, which also
+ * kobject_put to free sdp.
+ */
if (error)
- goto fail;
+ return error;
/* Mount an inter-node lock module, check for local optimizations */
-fail_sys:
- gfs_sys_fs_del(sdp);
-
fail:
- vfree(sdp);
+ /* gfs_sys_fs_del must be the last thing we do, since it causes
+ * sysfs to call function gfs2_sbd_release, which frees sdp. */
+ gfs_sys_fs_del(sdp);
sb->s_fs_info = NULL;
-
return error;
}