diff options
author | Al Viro <viro@zeniv.linux.org.uk> | 2013-12-10 14:43:54 -0500 |
---|---|---|
committer | Al Viro <viro@zeniv.linux.org.uk> | 2014-01-25 03:13:01 -0500 |
commit | 842a859db26b707f06fc9fbbb9137a9b90910e49 (patch) | |
tree | ae68674194641b9ee213840bccac89836e3ba8cb /fs | |
parent | 96c8c442117859cd95b5b57836ff374ff43f0564 (diff) |
affs: use ->kill_sb() to simplify ->put_super() and failure exits of ->mount()
... and return saner errors from ->mount(), while we are at it
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
Diffstat (limited to 'fs')
-rw-r--r-- | fs/affs/super.c | 57 |
1 files changed, 25 insertions, 32 deletions
diff --git a/fs/affs/super.c b/fs/affs/super.c index 45161a832bbc..d098731b82ff 100644 --- a/fs/affs/super.c +++ b/fs/affs/super.c | |||
@@ -49,11 +49,6 @@ affs_put_super(struct super_block *sb) | |||
49 | pr_debug("AFFS: put_super()\n"); | 49 | pr_debug("AFFS: put_super()\n"); |
50 | 50 | ||
51 | cancel_delayed_work_sync(&sbi->sb_work); | 51 | cancel_delayed_work_sync(&sbi->sb_work); |
52 | kfree(sbi->s_prefix); | ||
53 | affs_free_bitmap(sb); | ||
54 | affs_brelse(sbi->s_root_bh); | ||
55 | kfree(sbi); | ||
56 | sb->s_fs_info = NULL; | ||
57 | } | 52 | } |
58 | 53 | ||
59 | static int | 54 | static int |
@@ -316,7 +311,7 @@ static int affs_fill_super(struct super_block *sb, void *data, int silent) | |||
316 | unsigned long mount_flags; | 311 | unsigned long mount_flags; |
317 | int tmp_flags; /* fix remount prototype... */ | 312 | int tmp_flags; /* fix remount prototype... */ |
318 | u8 sig[4]; | 313 | u8 sig[4]; |
319 | int ret = -EINVAL; | 314 | int ret; |
320 | 315 | ||
321 | save_mount_options(sb, data); | 316 | save_mount_options(sb, data); |
322 | 317 | ||
@@ -412,17 +407,19 @@ static int affs_fill_super(struct super_block *sb, void *data, int silent) | |||
412 | if (!silent) | 407 | if (!silent) |
413 | printk(KERN_ERR "AFFS: No valid root block on device %s\n", | 408 | printk(KERN_ERR "AFFS: No valid root block on device %s\n", |
414 | sb->s_id); | 409 | sb->s_id); |
415 | goto out_error; | 410 | return -EINVAL; |
416 | 411 | ||
417 | /* N.B. after this point bh must be released */ | 412 | /* N.B. after this point bh must be released */ |
418 | got_root: | 413 | got_root: |
414 | /* Keep super block in cache */ | ||
415 | sbi->s_root_bh = root_bh; | ||
419 | root_block = sbi->s_root_block; | 416 | root_block = sbi->s_root_block; |
420 | 417 | ||
421 | /* Find out which kind of FS we have */ | 418 | /* Find out which kind of FS we have */ |
422 | boot_bh = sb_bread(sb, 0); | 419 | boot_bh = sb_bread(sb, 0); |
423 | if (!boot_bh) { | 420 | if (!boot_bh) { |
424 | printk(KERN_ERR "AFFS: Cannot read boot block\n"); | 421 | printk(KERN_ERR "AFFS: Cannot read boot block\n"); |
425 | goto out_error; | 422 | return -EINVAL; |
426 | } | 423 | } |
427 | memcpy(sig, boot_bh->b_data, 4); | 424 | memcpy(sig, boot_bh->b_data, 4); |
428 | brelse(boot_bh); | 425 | brelse(boot_bh); |
@@ -471,7 +468,7 @@ got_root: | |||
471 | default: | 468 | default: |
472 | printk(KERN_ERR "AFFS: Unknown filesystem on device %s: %08X\n", | 469 | printk(KERN_ERR "AFFS: Unknown filesystem on device %s: %08X\n", |
473 | sb->s_id, chksum); | 470 | sb->s_id, chksum); |
474 | goto out_error; | 471 | return -EINVAL; |
475 | } | 472 | } |
476 | 473 | ||
477 | if (mount_flags & SF_VERBOSE) { | 474 | if (mount_flags & SF_VERBOSE) { |
@@ -488,22 +485,17 @@ got_root: | |||
488 | if (sbi->s_flags & SF_OFS) | 485 | if (sbi->s_flags & SF_OFS) |
489 | sbi->s_data_blksize -= 24; | 486 | sbi->s_data_blksize -= 24; |
490 | 487 | ||
491 | /* Keep super block in cache */ | ||
492 | sbi->s_root_bh = root_bh; | ||
493 | /* N.B. after this point s_root_bh must be released */ | ||
494 | |||
495 | tmp_flags = sb->s_flags; | 488 | tmp_flags = sb->s_flags; |
496 | if (affs_init_bitmap(sb, &tmp_flags)) | 489 | ret = affs_init_bitmap(sb, &tmp_flags); |
497 | goto out_error; | 490 | if (ret) |
491 | return ret; | ||
498 | sb->s_flags = tmp_flags; | 492 | sb->s_flags = tmp_flags; |
499 | 493 | ||
500 | /* set up enough so that it can read an inode */ | 494 | /* set up enough so that it can read an inode */ |
501 | 495 | ||
502 | root_inode = affs_iget(sb, root_block); | 496 | root_inode = affs_iget(sb, root_block); |
503 | if (IS_ERR(root_inode)) { | 497 | if (IS_ERR(root_inode)) |
504 | ret = PTR_ERR(root_inode); | 498 | return PTR_ERR(root_inode); |
505 | goto out_error; | ||
506 | } | ||
507 | 499 | ||
508 | if (AFFS_SB(sb)->s_flags & SF_INTL) | 500 | if (AFFS_SB(sb)->s_flags & SF_INTL) |
509 | sb->s_d_op = &affs_intl_dentry_operations; | 501 | sb->s_d_op = &affs_intl_dentry_operations; |
@@ -513,22 +505,11 @@ got_root: | |||
513 | sb->s_root = d_make_root(root_inode); | 505 | sb->s_root = d_make_root(root_inode); |
514 | if (!sb->s_root) { | 506 | if (!sb->s_root) { |
515 | printk(KERN_ERR "AFFS: Get root inode failed\n"); | 507 | printk(KERN_ERR "AFFS: Get root inode failed\n"); |
516 | goto out_error; | 508 | return -ENOMEM; |
517 | } | 509 | } |
518 | 510 | ||
519 | pr_debug("AFFS: s_flags=%lX\n",sb->s_flags); | 511 | pr_debug("AFFS: s_flags=%lX\n",sb->s_flags); |
520 | return 0; | 512 | return 0; |
521 | |||
522 | /* | ||
523 | * Begin the cascaded cleanup ... | ||
524 | */ | ||
525 | out_error: | ||
526 | kfree(sbi->s_bitmap); | ||
527 | affs_brelse(root_bh); | ||
528 | kfree(sbi->s_prefix); | ||
529 | kfree(sbi); | ||
530 | sb->s_fs_info = NULL; | ||
531 | return ret; | ||
532 | } | 513 | } |
533 | 514 | ||
534 | static int | 515 | static int |
@@ -615,11 +596,23 @@ static struct dentry *affs_mount(struct file_system_type *fs_type, | |||
615 | return mount_bdev(fs_type, flags, dev_name, data, affs_fill_super); | 596 | return mount_bdev(fs_type, flags, dev_name, data, affs_fill_super); |
616 | } | 597 | } |
617 | 598 | ||
599 | static void affs_kill_sb(struct super_block *sb) | ||
600 | { | ||
601 | struct affs_sb_info *sbi = AFFS_SB(sb); | ||
602 | kill_block_super(sb); | ||
603 | if (sbi) { | ||
604 | affs_free_bitmap(sb); | ||
605 | affs_brelse(sbi->s_root_bh); | ||
606 | kfree(sbi->s_prefix); | ||
607 | kfree(sbi); | ||
608 | } | ||
609 | } | ||
610 | |||
618 | static struct file_system_type affs_fs_type = { | 611 | static struct file_system_type affs_fs_type = { |
619 | .owner = THIS_MODULE, | 612 | .owner = THIS_MODULE, |
620 | .name = "affs", | 613 | .name = "affs", |
621 | .mount = affs_mount, | 614 | .mount = affs_mount, |
622 | .kill_sb = kill_block_super, | 615 | .kill_sb = affs_kill_sb, |
623 | .fs_flags = FS_REQUIRES_DEV, | 616 | .fs_flags = FS_REQUIRES_DEV, |
624 | }; | 617 | }; |
625 | MODULE_ALIAS_FS("affs"); | 618 | MODULE_ALIAS_FS("affs"); |