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/affs | |
| 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/affs')
| -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"); |
