diff options
author | Chris Mason <clm@fb.com> | 2015-10-12 19:24:15 -0400 |
---|---|---|
committer | Chris Mason <clm@fb.com> | 2015-10-12 19:24:15 -0400 |
commit | 62fb50ab7c903357c92cef2f7677235b92ac575f (patch) | |
tree | 28f66d4e2c14b508b6b24795bfadf11aaada2d75 /fs/btrfs/disk-io.c | |
parent | 640926ffdda7e817965d3bfb5bbbc51598ccf49b (diff) | |
parent | 73416dab235e5ff030e3b3c61da0cd6ced324fc9 (diff) |
Merge branch 'anand/sysfs-updates-v4.3-rc3' of git://git.kernel.org/pub/scm/linux/kernel/git/kdave/linux into for-linus-4.4
Signed-off-by: Chris Mason <clm@fb.com>
Diffstat (limited to 'fs/btrfs/disk-io.c')
-rw-r--r-- | fs/btrfs/disk-io.c | 69 |
1 files changed, 47 insertions, 22 deletions
diff --git a/fs/btrfs/disk-io.c b/fs/btrfs/disk-io.c index 75f84e4c2033..7f934cccc98d 100644 --- a/fs/btrfs/disk-io.c +++ b/fs/btrfs/disk-io.c | |||
@@ -2375,7 +2375,7 @@ static int btrfs_replay_log(struct btrfs_fs_info *fs_info, | |||
2375 | /* returns with log_tree_root freed on success */ | 2375 | /* returns with log_tree_root freed on success */ |
2376 | ret = btrfs_recover_log_trees(log_tree_root); | 2376 | ret = btrfs_recover_log_trees(log_tree_root); |
2377 | if (ret) { | 2377 | if (ret) { |
2378 | btrfs_error(tree_root->fs_info, ret, | 2378 | btrfs_std_error(tree_root->fs_info, ret, |
2379 | "Failed to recover log tree"); | 2379 | "Failed to recover log tree"); |
2380 | free_extent_buffer(log_tree_root->node); | 2380 | free_extent_buffer(log_tree_root->node); |
2381 | kfree(log_tree_root); | 2381 | kfree(log_tree_root); |
@@ -2651,8 +2651,8 @@ int open_ctree(struct super_block *sb, | |||
2651 | * Read super block and check the signature bytes only | 2651 | * Read super block and check the signature bytes only |
2652 | */ | 2652 | */ |
2653 | bh = btrfs_read_dev_super(fs_devices->latest_bdev); | 2653 | bh = btrfs_read_dev_super(fs_devices->latest_bdev); |
2654 | if (!bh) { | 2654 | if (IS_ERR(bh)) { |
2655 | err = -EINVAL; | 2655 | err = PTR_ERR(bh); |
2656 | goto fail_alloc; | 2656 | goto fail_alloc; |
2657 | } | 2657 | } |
2658 | 2658 | ||
@@ -2935,7 +2935,7 @@ retry_root_backup: | |||
2935 | goto fail_fsdev_sysfs; | 2935 | goto fail_fsdev_sysfs; |
2936 | } | 2936 | } |
2937 | 2937 | ||
2938 | ret = btrfs_sysfs_add_one(fs_info); | 2938 | ret = btrfs_sysfs_add_mounted(fs_info); |
2939 | if (ret) { | 2939 | if (ret) { |
2940 | pr_err("BTRFS: failed to init sysfs interface: %d\n", ret); | 2940 | pr_err("BTRFS: failed to init sysfs interface: %d\n", ret); |
2941 | goto fail_fsdev_sysfs; | 2941 | goto fail_fsdev_sysfs; |
@@ -3115,7 +3115,7 @@ fail_cleaner: | |||
3115 | filemap_write_and_wait(fs_info->btree_inode->i_mapping); | 3115 | filemap_write_and_wait(fs_info->btree_inode->i_mapping); |
3116 | 3116 | ||
3117 | fail_sysfs: | 3117 | fail_sysfs: |
3118 | btrfs_sysfs_remove_one(fs_info); | 3118 | btrfs_sysfs_remove_mounted(fs_info); |
3119 | 3119 | ||
3120 | fail_fsdev_sysfs: | 3120 | fail_fsdev_sysfs: |
3121 | btrfs_sysfs_remove_fsid(fs_info->fs_devices); | 3121 | btrfs_sysfs_remove_fsid(fs_info->fs_devices); |
@@ -3190,6 +3190,37 @@ static void btrfs_end_buffer_write_sync(struct buffer_head *bh, int uptodate) | |||
3190 | put_bh(bh); | 3190 | put_bh(bh); |
3191 | } | 3191 | } |
3192 | 3192 | ||
3193 | int btrfs_read_dev_one_super(struct block_device *bdev, int copy_num, | ||
3194 | struct buffer_head **bh_ret) | ||
3195 | { | ||
3196 | struct buffer_head *bh; | ||
3197 | struct btrfs_super_block *super; | ||
3198 | u64 bytenr; | ||
3199 | |||
3200 | bytenr = btrfs_sb_offset(copy_num); | ||
3201 | if (bytenr + BTRFS_SUPER_INFO_SIZE >= i_size_read(bdev->bd_inode)) | ||
3202 | return -EINVAL; | ||
3203 | |||
3204 | bh = __bread(bdev, bytenr / 4096, BTRFS_SUPER_INFO_SIZE); | ||
3205 | /* | ||
3206 | * If we fail to read from the underlying devices, as of now | ||
3207 | * the best option we have is to mark it EIO. | ||
3208 | */ | ||
3209 | if (!bh) | ||
3210 | return -EIO; | ||
3211 | |||
3212 | super = (struct btrfs_super_block *)bh->b_data; | ||
3213 | if (btrfs_super_bytenr(super) != bytenr || | ||
3214 | btrfs_super_magic(super) != BTRFS_MAGIC) { | ||
3215 | brelse(bh); | ||
3216 | return -EINVAL; | ||
3217 | } | ||
3218 | |||
3219 | *bh_ret = bh; | ||
3220 | return 0; | ||
3221 | } | ||
3222 | |||
3223 | |||
3193 | struct buffer_head *btrfs_read_dev_super(struct block_device *bdev) | 3224 | struct buffer_head *btrfs_read_dev_super(struct block_device *bdev) |
3194 | { | 3225 | { |
3195 | struct buffer_head *bh; | 3226 | struct buffer_head *bh; |
@@ -3197,7 +3228,7 @@ struct buffer_head *btrfs_read_dev_super(struct block_device *bdev) | |||
3197 | struct btrfs_super_block *super; | 3228 | struct btrfs_super_block *super; |
3198 | int i; | 3229 | int i; |
3199 | u64 transid = 0; | 3230 | u64 transid = 0; |
3200 | u64 bytenr; | 3231 | int ret = -EINVAL; |
3201 | 3232 | ||
3202 | /* we would like to check all the supers, but that would make | 3233 | /* we would like to check all the supers, but that would make |
3203 | * a btrfs mount succeed after a mkfs from a different FS. | 3234 | * a btrfs mount succeed after a mkfs from a different FS. |
@@ -3205,21 +3236,11 @@ struct buffer_head *btrfs_read_dev_super(struct block_device *bdev) | |||
3205 | * later supers, using BTRFS_SUPER_MIRROR_MAX instead | 3236 | * later supers, using BTRFS_SUPER_MIRROR_MAX instead |
3206 | */ | 3237 | */ |
3207 | for (i = 0; i < 1; i++) { | 3238 | for (i = 0; i < 1; i++) { |
3208 | bytenr = btrfs_sb_offset(i); | 3239 | ret = btrfs_read_dev_one_super(bdev, i, &bh); |
3209 | if (bytenr + BTRFS_SUPER_INFO_SIZE >= | 3240 | if (ret) |
3210 | i_size_read(bdev->bd_inode)) | ||
3211 | break; | ||
3212 | bh = __bread(bdev, bytenr / 4096, | ||
3213 | BTRFS_SUPER_INFO_SIZE); | ||
3214 | if (!bh) | ||
3215 | continue; | 3241 | continue; |
3216 | 3242 | ||
3217 | super = (struct btrfs_super_block *)bh->b_data; | 3243 | super = (struct btrfs_super_block *)bh->b_data; |
3218 | if (btrfs_super_bytenr(super) != bytenr || | ||
3219 | btrfs_super_magic(super) != BTRFS_MAGIC) { | ||
3220 | brelse(bh); | ||
3221 | continue; | ||
3222 | } | ||
3223 | 3244 | ||
3224 | if (!latest || btrfs_super_generation(super) > transid) { | 3245 | if (!latest || btrfs_super_generation(super) > transid) { |
3225 | brelse(latest); | 3246 | brelse(latest); |
@@ -3229,6 +3250,10 @@ struct buffer_head *btrfs_read_dev_super(struct block_device *bdev) | |||
3229 | brelse(bh); | 3250 | brelse(bh); |
3230 | } | 3251 | } |
3231 | } | 3252 | } |
3253 | |||
3254 | if (!latest) | ||
3255 | return ERR_PTR(ret); | ||
3256 | |||
3232 | return latest; | 3257 | return latest; |
3233 | } | 3258 | } |
3234 | 3259 | ||
@@ -3547,7 +3572,7 @@ static int write_all_supers(struct btrfs_root *root, int max_mirrors) | |||
3547 | if (ret) { | 3572 | if (ret) { |
3548 | mutex_unlock( | 3573 | mutex_unlock( |
3549 | &root->fs_info->fs_devices->device_list_mutex); | 3574 | &root->fs_info->fs_devices->device_list_mutex); |
3550 | btrfs_error(root->fs_info, ret, | 3575 | btrfs_std_error(root->fs_info, ret, |
3551 | "errors while submitting device barriers."); | 3576 | "errors while submitting device barriers."); |
3552 | return ret; | 3577 | return ret; |
3553 | } | 3578 | } |
@@ -3587,7 +3612,7 @@ static int write_all_supers(struct btrfs_root *root, int max_mirrors) | |||
3587 | mutex_unlock(&root->fs_info->fs_devices->device_list_mutex); | 3612 | mutex_unlock(&root->fs_info->fs_devices->device_list_mutex); |
3588 | 3613 | ||
3589 | /* FUA is masked off if unsupported and can't be the reason */ | 3614 | /* FUA is masked off if unsupported and can't be the reason */ |
3590 | btrfs_error(root->fs_info, -EIO, | 3615 | btrfs_std_error(root->fs_info, -EIO, |
3591 | "%d errors while writing supers", total_errors); | 3616 | "%d errors while writing supers", total_errors); |
3592 | return -EIO; | 3617 | return -EIO; |
3593 | } | 3618 | } |
@@ -3605,7 +3630,7 @@ static int write_all_supers(struct btrfs_root *root, int max_mirrors) | |||
3605 | } | 3630 | } |
3606 | mutex_unlock(&root->fs_info->fs_devices->device_list_mutex); | 3631 | mutex_unlock(&root->fs_info->fs_devices->device_list_mutex); |
3607 | if (total_errors > max_errors) { | 3632 | if (total_errors > max_errors) { |
3608 | btrfs_error(root->fs_info, -EIO, | 3633 | btrfs_std_error(root->fs_info, -EIO, |
3609 | "%d errors while writing supers", total_errors); | 3634 | "%d errors while writing supers", total_errors); |
3610 | return -EIO; | 3635 | return -EIO; |
3611 | } | 3636 | } |
@@ -3791,7 +3816,7 @@ void close_ctree(struct btrfs_root *root) | |||
3791 | percpu_counter_sum(&fs_info->delalloc_bytes)); | 3816 | percpu_counter_sum(&fs_info->delalloc_bytes)); |
3792 | } | 3817 | } |
3793 | 3818 | ||
3794 | btrfs_sysfs_remove_one(fs_info); | 3819 | btrfs_sysfs_remove_mounted(fs_info); |
3795 | btrfs_sysfs_remove_fsid(fs_info->fs_devices); | 3820 | btrfs_sysfs_remove_fsid(fs_info->fs_devices); |
3796 | 3821 | ||
3797 | btrfs_free_fs_roots(fs_info); | 3822 | btrfs_free_fs_roots(fs_info); |