Commit 121b018f authored by Linus Torvalds's avatar Linus Torvalds

Merge tag 'for-4.20-rc4-tag' of git://git.kernel.org/pub/scm/linux/kernel/git/kdave/linux

Pull btrfs fixes from David Sterba:
 "Some of these bugs are being hit during testing so we'd like to get
  them merged, otherwise there are usual stability fixes for stable
  trees"

* tag 'for-4.20-rc4-tag' of git://git.kernel.org/pub/scm/linux/kernel/git/kdave/linux:
  btrfs: relocation: set trans to be NULL after ending transaction
  Btrfs: fix race between enabling quotas and subvolume creation
  Btrfs: send, fix infinite loop due to directory rename dependencies
  Btrfs: ensure path name is null terminated at btrfs_control_ioctl
  Btrfs: fix rare chances for data loss when doing a fast fsync
  btrfs: Always try all copies when reading extent buffers
parents 5b26f718 42a657f5
...@@ -477,9 +477,9 @@ static int btree_read_extent_buffer_pages(struct btrfs_fs_info *fs_info, ...@@ -477,9 +477,9 @@ static int btree_read_extent_buffer_pages(struct btrfs_fs_info *fs_info,
int mirror_num = 0; int mirror_num = 0;
int failed_mirror = 0; int failed_mirror = 0;
clear_bit(EXTENT_BUFFER_CORRUPT, &eb->bflags);
io_tree = &BTRFS_I(fs_info->btree_inode)->io_tree; io_tree = &BTRFS_I(fs_info->btree_inode)->io_tree;
while (1) { while (1) {
clear_bit(EXTENT_BUFFER_CORRUPT, &eb->bflags);
ret = read_extent_buffer_pages(io_tree, eb, WAIT_COMPLETE, ret = read_extent_buffer_pages(io_tree, eb, WAIT_COMPLETE,
mirror_num); mirror_num);
if (!ret) { if (!ret) {
...@@ -493,15 +493,6 @@ static int btree_read_extent_buffer_pages(struct btrfs_fs_info *fs_info, ...@@ -493,15 +493,6 @@ static int btree_read_extent_buffer_pages(struct btrfs_fs_info *fs_info,
break; break;
} }
/*
* This buffer's crc is fine, but its contents are corrupted, so
* there is no reason to read the other copies, they won't be
* any less wrong.
*/
if (test_bit(EXTENT_BUFFER_CORRUPT, &eb->bflags) ||
ret == -EUCLEAN)
break;
num_copies = btrfs_num_copies(fs_info, num_copies = btrfs_num_copies(fs_info,
eb->start, eb->len); eb->start, eb->len);
if (num_copies == 1) if (num_copies == 1)
......
...@@ -2088,6 +2088,30 @@ int btrfs_sync_file(struct file *file, loff_t start, loff_t end, int datasync) ...@@ -2088,6 +2088,30 @@ int btrfs_sync_file(struct file *file, loff_t start, loff_t end, int datasync)
atomic_inc(&root->log_batch); atomic_inc(&root->log_batch);
/*
* Before we acquired the inode's lock, someone may have dirtied more
* pages in the target range. We need to make sure that writeback for
* any such pages does not start while we are logging the inode, because
* if it does, any of the following might happen when we are not doing a
* full inode sync:
*
* 1) We log an extent after its writeback finishes but before its
* checksums are added to the csum tree, leading to -EIO errors
* when attempting to read the extent after a log replay.
*
* 2) We can end up logging an extent before its writeback finishes.
* Therefore after the log replay we will have a file extent item
* pointing to an unwritten extent (and no data checksums as well).
*
* So trigger writeback for any eventual new dirty pages and then we
* wait for all ordered extents to complete below.
*/
ret = start_ordered_ops(inode, start, end);
if (ret) {
inode_unlock(inode);
goto out;
}
/* /*
* We have to do this here to avoid the priority inversion of waiting on * We have to do this here to avoid the priority inversion of waiting on
* IO of a lower priority task while holding a transaciton open. * IO of a lower priority task while holding a transaciton open.
......
...@@ -2659,7 +2659,7 @@ int btrfs_qgroup_inherit(struct btrfs_trans_handle *trans, u64 srcid, ...@@ -2659,7 +2659,7 @@ int btrfs_qgroup_inherit(struct btrfs_trans_handle *trans, u64 srcid,
int i; int i;
u64 *i_qgroups; u64 *i_qgroups;
struct btrfs_fs_info *fs_info = trans->fs_info; struct btrfs_fs_info *fs_info = trans->fs_info;
struct btrfs_root *quota_root = fs_info->quota_root; struct btrfs_root *quota_root;
struct btrfs_qgroup *srcgroup; struct btrfs_qgroup *srcgroup;
struct btrfs_qgroup *dstgroup; struct btrfs_qgroup *dstgroup;
u32 level_size = 0; u32 level_size = 0;
...@@ -2669,6 +2669,7 @@ int btrfs_qgroup_inherit(struct btrfs_trans_handle *trans, u64 srcid, ...@@ -2669,6 +2669,7 @@ int btrfs_qgroup_inherit(struct btrfs_trans_handle *trans, u64 srcid,
if (!test_bit(BTRFS_FS_QUOTA_ENABLED, &fs_info->flags)) if (!test_bit(BTRFS_FS_QUOTA_ENABLED, &fs_info->flags))
goto out; goto out;
quota_root = fs_info->quota_root;
if (!quota_root) { if (!quota_root) {
ret = -EINVAL; ret = -EINVAL;
goto out; goto out;
......
...@@ -3959,6 +3959,7 @@ static noinline_for_stack int relocate_block_group(struct reloc_control *rc) ...@@ -3959,6 +3959,7 @@ static noinline_for_stack int relocate_block_group(struct reloc_control *rc)
restart: restart:
if (update_backref_cache(trans, &rc->backref_cache)) { if (update_backref_cache(trans, &rc->backref_cache)) {
btrfs_end_transaction(trans); btrfs_end_transaction(trans);
trans = NULL;
continue; continue;
} }
......
...@@ -3340,7 +3340,8 @@ static void free_pending_move(struct send_ctx *sctx, struct pending_dir_move *m) ...@@ -3340,7 +3340,8 @@ static void free_pending_move(struct send_ctx *sctx, struct pending_dir_move *m)
kfree(m); kfree(m);
} }
static void tail_append_pending_moves(struct pending_dir_move *moves, static void tail_append_pending_moves(struct send_ctx *sctx,
struct pending_dir_move *moves,
struct list_head *stack) struct list_head *stack)
{ {
if (list_empty(&moves->list)) { if (list_empty(&moves->list)) {
...@@ -3351,6 +3352,10 @@ static void tail_append_pending_moves(struct pending_dir_move *moves, ...@@ -3351,6 +3352,10 @@ static void tail_append_pending_moves(struct pending_dir_move *moves,
list_add_tail(&moves->list, stack); list_add_tail(&moves->list, stack);
list_splice_tail(&list, stack); list_splice_tail(&list, stack);
} }
if (!RB_EMPTY_NODE(&moves->node)) {
rb_erase(&moves->node, &sctx->pending_dir_moves);
RB_CLEAR_NODE(&moves->node);
}
} }
static int apply_children_dir_moves(struct send_ctx *sctx) 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,7 +3370,7 @@ static int apply_children_dir_moves(struct send_ctx *sctx)
return 0; return 0;
INIT_LIST_HEAD(&stack); INIT_LIST_HEAD(&stack);
tail_append_pending_moves(pm, &stack); tail_append_pending_moves(sctx, pm, &stack);
while (!list_empty(&stack)) { while (!list_empty(&stack)) {
pm = list_first_entry(&stack, struct pending_dir_move, list); 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,7 +3381,7 @@ static int apply_children_dir_moves(struct send_ctx *sctx)
goto out; goto out;
pm = get_pending_dir_moves(sctx, parent_ino); pm = get_pending_dir_moves(sctx, parent_ino);
if (pm) if (pm)
tail_append_pending_moves(pm, &stack); tail_append_pending_moves(sctx, pm, &stack);
} }
return 0; return 0;
......
...@@ -2237,6 +2237,7 @@ static long btrfs_control_ioctl(struct file *file, unsigned int cmd, ...@@ -2237,6 +2237,7 @@ static long btrfs_control_ioctl(struct file *file, unsigned int cmd,
vol = memdup_user((void __user *)arg, sizeof(*vol)); vol = memdup_user((void __user *)arg, sizeof(*vol));
if (IS_ERR(vol)) if (IS_ERR(vol))
return PTR_ERR(vol); return PTR_ERR(vol);
vol->name[BTRFS_PATH_NAME_MAX] = '\0';
switch (cmd) { switch (cmd) {
case BTRFS_IOC_SCAN_DEV: case BTRFS_IOC_SCAN_DEV:
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment