diff options
author | Ingo Molnar <mingo@elte.hu> | 2009-04-07 02:16:50 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2009-04-07 10:39:59 -0400 |
commit | f8201abcb2badce7eaa6a3715f9a228cfd88a453 (patch) | |
tree | b635d8ad39ada141b06884e91ad7de41c44a2f0e /fs/ramfs | |
parent | 4ef4327b30957a16619ac7d47c749465e62de8c3 (diff) |
ramfs: fix double freeing s_fs_info on failed mount
If ramfs mount fails, s_fs_info will be freed twice in ramfs_fill_super()
and ramfs_kill_sb(), leading to kernel oops.
Consolidate and beautify the code.
Make sure s_fs_info and s_root are in known good states.
Acked-by: Wu Fengguang <fengguang.wu@intel.com>
Signed-off-by: Ingo Molnar <mingo@elte.hu>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'fs/ramfs')
-rw-r--r-- | fs/ramfs/inode.c | 19 |
1 files changed, 11 insertions, 8 deletions
diff --git a/fs/ramfs/inode.c b/fs/ramfs/inode.c index a404fb88e456..3a6b193d8444 100644 --- a/fs/ramfs/inode.c +++ b/fs/ramfs/inode.c | |||
@@ -221,22 +221,23 @@ static int ramfs_fill_super(struct super_block * sb, void * data, int silent) | |||
221 | save_mount_options(sb, data); | 221 | save_mount_options(sb, data); |
222 | 222 | ||
223 | fsi = kzalloc(sizeof(struct ramfs_fs_info), GFP_KERNEL); | 223 | fsi = kzalloc(sizeof(struct ramfs_fs_info), GFP_KERNEL); |
224 | sb->s_fs_info = fsi; | ||
224 | if (!fsi) { | 225 | if (!fsi) { |
225 | err = -ENOMEM; | 226 | err = -ENOMEM; |
226 | goto fail; | 227 | goto fail; |
227 | } | 228 | } |
228 | sb->s_fs_info = fsi; | ||
229 | 229 | ||
230 | err = ramfs_parse_options(data, &fsi->mount_opts); | 230 | err = ramfs_parse_options(data, &fsi->mount_opts); |
231 | if (err) | 231 | if (err) |
232 | goto fail; | 232 | goto fail; |
233 | 233 | ||
234 | sb->s_maxbytes = MAX_LFS_FILESIZE; | 234 | sb->s_maxbytes = MAX_LFS_FILESIZE; |
235 | sb->s_blocksize = PAGE_CACHE_SIZE; | 235 | sb->s_blocksize = PAGE_CACHE_SIZE; |
236 | sb->s_blocksize_bits = PAGE_CACHE_SHIFT; | 236 | sb->s_blocksize_bits = PAGE_CACHE_SHIFT; |
237 | sb->s_magic = RAMFS_MAGIC; | 237 | sb->s_magic = RAMFS_MAGIC; |
238 | sb->s_op = &ramfs_ops; | 238 | sb->s_op = &ramfs_ops; |
239 | sb->s_time_gran = 1; | 239 | sb->s_time_gran = 1; |
240 | |||
240 | inode = ramfs_get_inode(sb, S_IFDIR | fsi->mount_opts.mode, 0); | 241 | inode = ramfs_get_inode(sb, S_IFDIR | fsi->mount_opts.mode, 0); |
241 | if (!inode) { | 242 | if (!inode) { |
242 | err = -ENOMEM; | 243 | err = -ENOMEM; |
@@ -244,14 +245,16 @@ static int ramfs_fill_super(struct super_block * sb, void * data, int silent) | |||
244 | } | 245 | } |
245 | 246 | ||
246 | root = d_alloc_root(inode); | 247 | root = d_alloc_root(inode); |
248 | sb->s_root = root; | ||
247 | if (!root) { | 249 | if (!root) { |
248 | err = -ENOMEM; | 250 | err = -ENOMEM; |
249 | goto fail; | 251 | goto fail; |
250 | } | 252 | } |
251 | sb->s_root = root; | 253 | |
252 | return 0; | 254 | return 0; |
253 | fail: | 255 | fail: |
254 | kfree(fsi); | 256 | kfree(fsi); |
257 | sb->s_fs_info = NULL; | ||
255 | iput(inode); | 258 | iput(inode); |
256 | return err; | 259 | return err; |
257 | } | 260 | } |