Commit 51090c5d authored by Linus Torvalds's avatar Linus Torvalds

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

Pull btrfs fixes from David Sterba:
 "This contains a few fixes (error handling, quota leak, FUA vs
  nobarrier mount option).

  There's one one worth mentioning separately - an off-by-one fix that
  leads to overwriting first byte of an adjacent page with 0, out of
  bounds of the memory allocated by an ioctl. This is under a privileged
  part of the ioctl, can be triggerd in some subvolume layouts"

* tag 'for-4.15-rc3-tag' of git://git.kernel.org/pub/scm/linux/kernel/git/kdave/linux:
  btrfs: Fix possible off-by-one in btrfs_search_path_in_tree
  Btrfs: disable FUA if mounted with nobarrier
  btrfs: fix missing error return in btrfs_drop_snapshot
  btrfs: handle errors while updating refcounts in update_ref_for_cow
  btrfs: Fix quota reservation leak on preallocated files
parents 9c02e060 c8bcbfbd
...@@ -1032,14 +1032,17 @@ static noinline int update_ref_for_cow(struct btrfs_trans_handle *trans, ...@@ -1032,14 +1032,17 @@ static noinline int update_ref_for_cow(struct btrfs_trans_handle *trans,
root->root_key.objectid == BTRFS_TREE_RELOC_OBJECTID) && root->root_key.objectid == BTRFS_TREE_RELOC_OBJECTID) &&
!(flags & BTRFS_BLOCK_FLAG_FULL_BACKREF)) { !(flags & BTRFS_BLOCK_FLAG_FULL_BACKREF)) {
ret = btrfs_inc_ref(trans, root, buf, 1); ret = btrfs_inc_ref(trans, root, buf, 1);
BUG_ON(ret); /* -ENOMEM */ if (ret)
return ret;
if (root->root_key.objectid == if (root->root_key.objectid ==
BTRFS_TREE_RELOC_OBJECTID) { BTRFS_TREE_RELOC_OBJECTID) {
ret = btrfs_dec_ref(trans, root, buf, 0); ret = btrfs_dec_ref(trans, root, buf, 0);
BUG_ON(ret); /* -ENOMEM */ if (ret)
return ret;
ret = btrfs_inc_ref(trans, root, cow, 1); ret = btrfs_inc_ref(trans, root, cow, 1);
BUG_ON(ret); /* -ENOMEM */ if (ret)
return ret;
} }
new_flags |= BTRFS_BLOCK_FLAG_FULL_BACKREF; new_flags |= BTRFS_BLOCK_FLAG_FULL_BACKREF;
} else { } else {
...@@ -1049,7 +1052,8 @@ static noinline int update_ref_for_cow(struct btrfs_trans_handle *trans, ...@@ -1049,7 +1052,8 @@ static noinline int update_ref_for_cow(struct btrfs_trans_handle *trans,
ret = btrfs_inc_ref(trans, root, cow, 1); ret = btrfs_inc_ref(trans, root, cow, 1);
else else
ret = btrfs_inc_ref(trans, root, cow, 0); ret = btrfs_inc_ref(trans, root, cow, 0);
BUG_ON(ret); /* -ENOMEM */ if (ret)
return ret;
} }
if (new_flags != 0) { if (new_flags != 0) {
int level = btrfs_header_level(buf); int level = btrfs_header_level(buf);
...@@ -1068,9 +1072,11 @@ static noinline int update_ref_for_cow(struct btrfs_trans_handle *trans, ...@@ -1068,9 +1072,11 @@ static noinline int update_ref_for_cow(struct btrfs_trans_handle *trans,
ret = btrfs_inc_ref(trans, root, cow, 1); ret = btrfs_inc_ref(trans, root, cow, 1);
else else
ret = btrfs_inc_ref(trans, root, cow, 0); ret = btrfs_inc_ref(trans, root, cow, 0);
BUG_ON(ret); /* -ENOMEM */ if (ret)
return ret;
ret = btrfs_dec_ref(trans, root, buf, 1); ret = btrfs_dec_ref(trans, root, buf, 1);
BUG_ON(ret); /* -ENOMEM */ if (ret)
return ret;
} }
clean_tree_block(fs_info, buf); clean_tree_block(fs_info, buf);
*last_ref = 1; *last_ref = 1;
......
...@@ -3231,6 +3231,7 @@ static int write_dev_supers(struct btrfs_device *device, ...@@ -3231,6 +3231,7 @@ static int write_dev_supers(struct btrfs_device *device,
int errors = 0; int errors = 0;
u32 crc; u32 crc;
u64 bytenr; u64 bytenr;
int op_flags;
if (max_mirrors == 0) if (max_mirrors == 0)
max_mirrors = BTRFS_SUPER_MIRROR_MAX; max_mirrors = BTRFS_SUPER_MIRROR_MAX;
...@@ -3273,13 +3274,10 @@ static int write_dev_supers(struct btrfs_device *device, ...@@ -3273,13 +3274,10 @@ static int write_dev_supers(struct btrfs_device *device,
* we fua the first super. The others we allow * we fua the first super. The others we allow
* to go down lazy. * to go down lazy.
*/ */
if (i == 0) { op_flags = REQ_SYNC | REQ_META | REQ_PRIO;
ret = btrfsic_submit_bh(REQ_OP_WRITE, if (i == 0 && !btrfs_test_opt(device->fs_info, NOBARRIER))
REQ_SYNC | REQ_FUA | REQ_META | REQ_PRIO, bh); op_flags |= REQ_FUA;
} else { ret = btrfsic_submit_bh(REQ_OP_WRITE, op_flags, bh);
ret = btrfsic_submit_bh(REQ_OP_WRITE,
REQ_SYNC | REQ_META | REQ_PRIO, bh);
}
if (ret) if (ret)
errors++; errors++;
} }
......
...@@ -9206,6 +9206,7 @@ int btrfs_drop_snapshot(struct btrfs_root *root, ...@@ -9206,6 +9206,7 @@ int btrfs_drop_snapshot(struct btrfs_root *root,
ret = btrfs_del_root(trans, fs_info, &root->root_key); ret = btrfs_del_root(trans, fs_info, &root->root_key);
if (ret) { if (ret) {
btrfs_abort_transaction(trans, ret); btrfs_abort_transaction(trans, ret);
err = ret;
goto out_end_trans; goto out_end_trans;
} }
......
...@@ -3005,6 +3005,8 @@ static int btrfs_finish_ordered_io(struct btrfs_ordered_extent *ordered_extent) ...@@ -3005,6 +3005,8 @@ static int btrfs_finish_ordered_io(struct btrfs_ordered_extent *ordered_extent)
compress_type = ordered_extent->compress_type; compress_type = ordered_extent->compress_type;
if (test_bit(BTRFS_ORDERED_PREALLOC, &ordered_extent->flags)) { if (test_bit(BTRFS_ORDERED_PREALLOC, &ordered_extent->flags)) {
BUG_ON(compress_type); BUG_ON(compress_type);
btrfs_qgroup_free_data(inode, NULL, ordered_extent->file_offset,
ordered_extent->len);
ret = btrfs_mark_extent_written(trans, BTRFS_I(inode), ret = btrfs_mark_extent_written(trans, BTRFS_I(inode),
ordered_extent->file_offset, ordered_extent->file_offset,
ordered_extent->file_offset + ordered_extent->file_offset +
......
...@@ -2206,7 +2206,7 @@ static noinline int btrfs_search_path_in_tree(struct btrfs_fs_info *info, ...@@ -2206,7 +2206,7 @@ static noinline int btrfs_search_path_in_tree(struct btrfs_fs_info *info,
if (!path) if (!path)
return -ENOMEM; return -ENOMEM;
ptr = &name[BTRFS_INO_LOOKUP_PATH_MAX]; ptr = &name[BTRFS_INO_LOOKUP_PATH_MAX - 1];
key.objectid = tree_id; key.objectid = tree_id;
key.type = BTRFS_ROOT_ITEM_KEY; key.type = BTRFS_ROOT_ITEM_KEY;
......
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