diff options
-rw-r--r-- | fs/btrfs/disk-io.c | 11 | ||||
-rw-r--r-- | fs/btrfs/file.c | 24 | ||||
-rw-r--r-- | fs/btrfs/qgroup.c | 3 | ||||
-rw-r--r-- | fs/btrfs/relocation.c | 1 | ||||
-rw-r--r-- | fs/btrfs/send.c | 11 | ||||
-rw-r--r-- | fs/btrfs/super.c | 1 |
6 files changed, 37 insertions, 14 deletions
diff --git a/fs/btrfs/disk-io.c b/fs/btrfs/disk-io.c index 3f0b6d1936e8..6d776717d8b3 100644 --- a/fs/btrfs/disk-io.c +++ b/fs/btrfs/disk-io.c | |||
@@ -477,9 +477,9 @@ static int btree_read_extent_buffer_pages(struct btrfs_fs_info *fs_info, | |||
477 | int mirror_num = 0; | 477 | int mirror_num = 0; |
478 | int failed_mirror = 0; | 478 | int failed_mirror = 0; |
479 | 479 | ||
480 | clear_bit(EXTENT_BUFFER_CORRUPT, &eb->bflags); | ||
481 | io_tree = &BTRFS_I(fs_info->btree_inode)->io_tree; | 480 | io_tree = &BTRFS_I(fs_info->btree_inode)->io_tree; |
482 | while (1) { | 481 | while (1) { |
482 | clear_bit(EXTENT_BUFFER_CORRUPT, &eb->bflags); | ||
483 | ret = read_extent_buffer_pages(io_tree, eb, WAIT_COMPLETE, | 483 | ret = read_extent_buffer_pages(io_tree, eb, WAIT_COMPLETE, |
484 | mirror_num); | 484 | mirror_num); |
485 | if (!ret) { | 485 | if (!ret) { |
@@ -493,15 +493,6 @@ static int btree_read_extent_buffer_pages(struct btrfs_fs_info *fs_info, | |||
493 | break; | 493 | break; |
494 | } | 494 | } |
495 | 495 | ||
496 | /* | ||
497 | * This buffer's crc is fine, but its contents are corrupted, so | ||
498 | * there is no reason to read the other copies, they won't be | ||
499 | * any less wrong. | ||
500 | */ | ||
501 | if (test_bit(EXTENT_BUFFER_CORRUPT, &eb->bflags) || | ||
502 | ret == -EUCLEAN) | ||
503 | break; | ||
504 | |||
505 | num_copies = btrfs_num_copies(fs_info, | 496 | num_copies = btrfs_num_copies(fs_info, |
506 | eb->start, eb->len); | 497 | eb->start, eb->len); |
507 | if (num_copies == 1) | 498 | if (num_copies == 1) |
diff --git a/fs/btrfs/file.c b/fs/btrfs/file.c index a3c22e16509b..58e93bce3036 100644 --- a/fs/btrfs/file.c +++ b/fs/btrfs/file.c | |||
@@ -2089,6 +2089,30 @@ int btrfs_sync_file(struct file *file, loff_t start, loff_t end, int datasync) | |||
2089 | atomic_inc(&root->log_batch); | 2089 | atomic_inc(&root->log_batch); |
2090 | 2090 | ||
2091 | /* | 2091 | /* |
2092 | * Before we acquired the inode's lock, someone may have dirtied more | ||
2093 | * pages in the target range. We need to make sure that writeback for | ||
2094 | * any such pages does not start while we are logging the inode, because | ||
2095 | * if it does, any of the following might happen when we are not doing a | ||
2096 | * full inode sync: | ||
2097 | * | ||
2098 | * 1) We log an extent after its writeback finishes but before its | ||
2099 | * checksums are added to the csum tree, leading to -EIO errors | ||
2100 | * when attempting to read the extent after a log replay. | ||
2101 | * | ||
2102 | * 2) We can end up logging an extent before its writeback finishes. | ||
2103 | * Therefore after the log replay we will have a file extent item | ||
2104 | * pointing to an unwritten extent (and no data checksums as well). | ||
2105 | * | ||
2106 | * So trigger writeback for any eventual new dirty pages and then we | ||
2107 | * wait for all ordered extents to complete below. | ||
2108 | */ | ||
2109 | ret = start_ordered_ops(inode, start, end); | ||
2110 | if (ret) { | ||
2111 | inode_unlock(inode); | ||
2112 | goto out; | ||
2113 | } | ||
2114 | |||
2115 | /* | ||
2092 | * We have to do this here to avoid the priority inversion of waiting on | 2116 | * We have to do this here to avoid the priority inversion of waiting on |
2093 | * IO of a lower priority task while holding a transaciton open. | 2117 | * IO of a lower priority task while holding a transaciton open. |
2094 | */ | 2118 | */ |
diff --git a/fs/btrfs/qgroup.c b/fs/btrfs/qgroup.c index 45868fd76209..f70825af6438 100644 --- a/fs/btrfs/qgroup.c +++ b/fs/btrfs/qgroup.c | |||
@@ -2659,7 +2659,7 @@ int btrfs_qgroup_inherit(struct btrfs_trans_handle *trans, u64 srcid, | |||
2659 | int i; | 2659 | int i; |
2660 | u64 *i_qgroups; | 2660 | u64 *i_qgroups; |
2661 | struct btrfs_fs_info *fs_info = trans->fs_info; | 2661 | struct btrfs_fs_info *fs_info = trans->fs_info; |
2662 | struct btrfs_root *quota_root = fs_info->quota_root; | 2662 | struct btrfs_root *quota_root; |
2663 | struct btrfs_qgroup *srcgroup; | 2663 | struct btrfs_qgroup *srcgroup; |
2664 | struct btrfs_qgroup *dstgroup; | 2664 | struct btrfs_qgroup *dstgroup; |
2665 | u32 level_size = 0; | 2665 | u32 level_size = 0; |
@@ -2669,6 +2669,7 @@ int btrfs_qgroup_inherit(struct btrfs_trans_handle *trans, u64 srcid, | |||
2669 | if (!test_bit(BTRFS_FS_QUOTA_ENABLED, &fs_info->flags)) | 2669 | if (!test_bit(BTRFS_FS_QUOTA_ENABLED, &fs_info->flags)) |
2670 | goto out; | 2670 | goto out; |
2671 | 2671 | ||
2672 | quota_root = fs_info->quota_root; | ||
2672 | if (!quota_root) { | 2673 | if (!quota_root) { |
2673 | ret = -EINVAL; | 2674 | ret = -EINVAL; |
2674 | goto out; | 2675 | goto out; |
diff --git a/fs/btrfs/relocation.c b/fs/btrfs/relocation.c index 924116f654a1..a3f75b8926d4 100644 --- a/fs/btrfs/relocation.c +++ b/fs/btrfs/relocation.c | |||
@@ -3959,6 +3959,7 @@ static noinline_for_stack int relocate_block_group(struct reloc_control *rc) | |||
3959 | restart: | 3959 | restart: |
3960 | if (update_backref_cache(trans, &rc->backref_cache)) { | 3960 | if (update_backref_cache(trans, &rc->backref_cache)) { |
3961 | btrfs_end_transaction(trans); | 3961 | btrfs_end_transaction(trans); |
3962 | trans = NULL; | ||
3962 | continue; | 3963 | continue; |
3963 | } | 3964 | } |
3964 | 3965 | ||
diff --git a/fs/btrfs/send.c b/fs/btrfs/send.c index 094cc1444a90..5be83b5a1b43 100644 --- a/fs/btrfs/send.c +++ b/fs/btrfs/send.c | |||
@@ -3340,7 +3340,8 @@ static void free_pending_move(struct send_ctx *sctx, struct pending_dir_move *m) | |||
3340 | kfree(m); | 3340 | kfree(m); |
3341 | } | 3341 | } |
3342 | 3342 | ||
3343 | static void tail_append_pending_moves(struct pending_dir_move *moves, | 3343 | static void tail_append_pending_moves(struct send_ctx *sctx, |
3344 | struct pending_dir_move *moves, | ||
3344 | struct list_head *stack) | 3345 | struct list_head *stack) |
3345 | { | 3346 | { |
3346 | if (list_empty(&moves->list)) { | 3347 | if (list_empty(&moves->list)) { |
@@ -3351,6 +3352,10 @@ static void tail_append_pending_moves(struct pending_dir_move *moves, | |||
3351 | list_add_tail(&moves->list, stack); | 3352 | list_add_tail(&moves->list, stack); |
3352 | list_splice_tail(&list, stack); | 3353 | list_splice_tail(&list, stack); |
3353 | } | 3354 | } |
3355 | if (!RB_EMPTY_NODE(&moves->node)) { | ||
3356 | rb_erase(&moves->node, &sctx->pending_dir_moves); | ||
3357 | RB_CLEAR_NODE(&moves->node); | ||
3358 | } | ||
3354 | } | 3359 | } |
3355 | 3360 | ||
3356 | static int apply_children_dir_moves(struct send_ctx *sctx) | 3361 | static int apply_children_dir_moves(struct send_ctx *sctx) |
@@ -3365,7 +3370,7 @@ static int apply_children_dir_moves(struct send_ctx *sctx) | |||
3365 | return 0; | 3370 | return 0; |
3366 | 3371 | ||
3367 | INIT_LIST_HEAD(&stack); | 3372 | INIT_LIST_HEAD(&stack); |
3368 | tail_append_pending_moves(pm, &stack); | 3373 | tail_append_pending_moves(sctx, pm, &stack); |
3369 | 3374 | ||
3370 | while (!list_empty(&stack)) { | 3375 | while (!list_empty(&stack)) { |
3371 | pm = list_first_entry(&stack, struct pending_dir_move, list); | 3376 | pm = list_first_entry(&stack, struct pending_dir_move, list); |
@@ -3376,7 +3381,7 @@ static int apply_children_dir_moves(struct send_ctx *sctx) | |||
3376 | goto out; | 3381 | goto out; |
3377 | pm = get_pending_dir_moves(sctx, parent_ino); | 3382 | pm = get_pending_dir_moves(sctx, parent_ino); |
3378 | if (pm) | 3383 | if (pm) |
3379 | tail_append_pending_moves(pm, &stack); | 3384 | tail_append_pending_moves(sctx, pm, &stack); |
3380 | } | 3385 | } |
3381 | return 0; | 3386 | return 0; |
3382 | 3387 | ||
diff --git a/fs/btrfs/super.c b/fs/btrfs/super.c index cbc9d0d2c12d..645fc81e2a94 100644 --- a/fs/btrfs/super.c +++ b/fs/btrfs/super.c | |||
@@ -2237,6 +2237,7 @@ static long btrfs_control_ioctl(struct file *file, unsigned int cmd, | |||
2237 | vol = memdup_user((void __user *)arg, sizeof(*vol)); | 2237 | vol = memdup_user((void __user *)arg, sizeof(*vol)); |
2238 | if (IS_ERR(vol)) | 2238 | if (IS_ERR(vol)) |
2239 | return PTR_ERR(vol); | 2239 | return PTR_ERR(vol); |
2240 | vol->name[BTRFS_PATH_NAME_MAX] = '\0'; | ||
2240 | 2241 | ||
2241 | switch (cmd) { | 2242 | switch (cmd) { |
2242 | case BTRFS_IOC_SCAN_DEV: | 2243 | case BTRFS_IOC_SCAN_DEV: |