Skip to content

Commit 51090c5

Browse files
committed
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
2 parents 9c02e06 + c8bcbfb commit 51090c5

File tree

5 files changed

+21
-14
lines changed

5 files changed

+21
-14
lines changed

fs/btrfs/ctree.c

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1032,14 +1032,17 @@ static noinline int update_ref_for_cow(struct btrfs_trans_handle *trans,
10321032
root->root_key.objectid == BTRFS_TREE_RELOC_OBJECTID) &&
10331033
!(flags & BTRFS_BLOCK_FLAG_FULL_BACKREF)) {
10341034
ret = btrfs_inc_ref(trans, root, buf, 1);
1035-
BUG_ON(ret); /* -ENOMEM */
1035+
if (ret)
1036+
return ret;
10361037

10371038
if (root->root_key.objectid ==
10381039
BTRFS_TREE_RELOC_OBJECTID) {
10391040
ret = btrfs_dec_ref(trans, root, buf, 0);
1040-
BUG_ON(ret); /* -ENOMEM */
1041+
if (ret)
1042+
return ret;
10411043
ret = btrfs_inc_ref(trans, root, cow, 1);
1042-
BUG_ON(ret); /* -ENOMEM */
1044+
if (ret)
1045+
return ret;
10431046
}
10441047
new_flags |= BTRFS_BLOCK_FLAG_FULL_BACKREF;
10451048
} else {
@@ -1049,7 +1052,8 @@ static noinline int update_ref_for_cow(struct btrfs_trans_handle *trans,
10491052
ret = btrfs_inc_ref(trans, root, cow, 1);
10501053
else
10511054
ret = btrfs_inc_ref(trans, root, cow, 0);
1052-
BUG_ON(ret); /* -ENOMEM */
1055+
if (ret)
1056+
return ret;
10531057
}
10541058
if (new_flags != 0) {
10551059
int level = btrfs_header_level(buf);
@@ -1068,9 +1072,11 @@ static noinline int update_ref_for_cow(struct btrfs_trans_handle *trans,
10681072
ret = btrfs_inc_ref(trans, root, cow, 1);
10691073
else
10701074
ret = btrfs_inc_ref(trans, root, cow, 0);
1071-
BUG_ON(ret); /* -ENOMEM */
1075+
if (ret)
1076+
return ret;
10721077
ret = btrfs_dec_ref(trans, root, buf, 1);
1073-
BUG_ON(ret); /* -ENOMEM */
1078+
if (ret)
1079+
return ret;
10741080
}
10751081
clean_tree_block(fs_info, buf);
10761082
*last_ref = 1;

fs/btrfs/disk-io.c

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -3231,6 +3231,7 @@ static int write_dev_supers(struct btrfs_device *device,
32313231
int errors = 0;
32323232
u32 crc;
32333233
u64 bytenr;
3234+
int op_flags;
32343235

32353236
if (max_mirrors == 0)
32363237
max_mirrors = BTRFS_SUPER_MIRROR_MAX;
@@ -3273,13 +3274,10 @@ static int write_dev_supers(struct btrfs_device *device,
32733274
* we fua the first super. The others we allow
32743275
* to go down lazy.
32753276
*/
3276-
if (i == 0) {
3277-
ret = btrfsic_submit_bh(REQ_OP_WRITE,
3278-
REQ_SYNC | REQ_FUA | REQ_META | REQ_PRIO, bh);
3279-
} else {
3280-
ret = btrfsic_submit_bh(REQ_OP_WRITE,
3281-
REQ_SYNC | REQ_META | REQ_PRIO, bh);
3282-
}
3277+
op_flags = REQ_SYNC | REQ_META | REQ_PRIO;
3278+
if (i == 0 && !btrfs_test_opt(device->fs_info, NOBARRIER))
3279+
op_flags |= REQ_FUA;
3280+
ret = btrfsic_submit_bh(REQ_OP_WRITE, op_flags, bh);
32833281
if (ret)
32843282
errors++;
32853283
}

fs/btrfs/extent-tree.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9206,6 +9206,7 @@ int btrfs_drop_snapshot(struct btrfs_root *root,
92069206
ret = btrfs_del_root(trans, fs_info, &root->root_key);
92079207
if (ret) {
92089208
btrfs_abort_transaction(trans, ret);
9209+
err = ret;
92099210
goto out_end_trans;
92109211
}
92119212

fs/btrfs/inode.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3005,6 +3005,8 @@ static int btrfs_finish_ordered_io(struct btrfs_ordered_extent *ordered_extent)
30053005
compress_type = ordered_extent->compress_type;
30063006
if (test_bit(BTRFS_ORDERED_PREALLOC, &ordered_extent->flags)) {
30073007
BUG_ON(compress_type);
3008+
btrfs_qgroup_free_data(inode, NULL, ordered_extent->file_offset,
3009+
ordered_extent->len);
30083010
ret = btrfs_mark_extent_written(trans, BTRFS_I(inode),
30093011
ordered_extent->file_offset,
30103012
ordered_extent->file_offset +

fs/btrfs/ioctl.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2206,7 +2206,7 @@ static noinline int btrfs_search_path_in_tree(struct btrfs_fs_info *info,
22062206
if (!path)
22072207
return -ENOMEM;
22082208

2209-
ptr = &name[BTRFS_INO_LOOKUP_PATH_MAX];
2209+
ptr = &name[BTRFS_INO_LOOKUP_PATH_MAX - 1];
22102210

22112211
key.objectid = tree_id;
22122212
key.type = BTRFS_ROOT_ITEM_KEY;

0 commit comments

Comments
 (0)