summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--fs/btrfs/disk-io.c11
-rw-r--r--fs/btrfs/file.c24
-rw-r--r--fs/btrfs/qgroup.c3
-rw-r--r--fs/btrfs/relocation.c1
-rw-r--r--fs/btrfs/send.c11
-rw-r--r--fs/btrfs/super.c1
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)
3959restart: 3959restart:
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
3343static void tail_append_pending_moves(struct pending_dir_move *moves, 3343static 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
3356static int apply_children_dir_moves(struct send_ctx *sctx) 3361static 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: