aboutsummaryrefslogtreecommitdiffstats
path: root/fs/btrfs/disk-io.c
diff options
context:
space:
mode:
authorChris Mason <clm@fb.com>2015-10-12 19:24:15 -0400
committerChris Mason <clm@fb.com>2015-10-12 19:24:15 -0400
commit62fb50ab7c903357c92cef2f7677235b92ac575f (patch)
tree28f66d4e2c14b508b6b24795bfadf11aaada2d75 /fs/btrfs/disk-io.c
parent640926ffdda7e817965d3bfb5bbbc51598ccf49b (diff)
parent73416dab235e5ff030e3b3c61da0cd6ced324fc9 (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.c69
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
3117fail_sysfs: 3117fail_sysfs:
3118 btrfs_sysfs_remove_one(fs_info); 3118 btrfs_sysfs_remove_mounted(fs_info);
3119 3119
3120fail_fsdev_sysfs: 3120fail_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
3193int 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
3193struct buffer_head *btrfs_read_dev_super(struct block_device *bdev) 3224struct 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);