Skip to content

Commit 9bacdd8

Browse files
committed
Merge tag 'for-6.7-rc1-tag' of git://git.kernel.org/pub/scm/linux/kernel/git/kdave/linux
Pull btrfs fixes from David Sterba: - fix potential overflow in returned value from SEARCH_TREE_V2 ioctl on 32bit architecture - zoned mode fixes: - drop unnecessary write pointer check for RAID0/RAID1/RAID10 profiles, now it works because of raid-stripe-tree - wait for finishing the zone when direct IO needs a new allocation - simple quota fixes: - pass correct owning root pointer when cleaning up an aborted transaction - fix leaking some structures when processing delayed refs - change key type number of BTRFS_EXTENT_OWNER_REF_KEY, reorder it before inline refs that are supposed to be sorted, keeping the original number would complicate a lot of things; this change needs an updated version of btrfs-progs to work and filesystems need to be recreated - fix error pointer dereference after failure to allocate fs devices - fix race between accounting qgroup extents and removing a qgroup * tag 'for-6.7-rc1-tag' of git://git.kernel.org/pub/scm/linux/kernel/git/kdave/linux: btrfs: make OWNER_REF_KEY type value smallest among inline refs btrfs: fix qgroup record leaks when using simple quotas btrfs: fix race between accounting qgroup extents and removing a qgroup btrfs: fix error pointer dereference after failure to allocate fs devices btrfs: make found_logical_ret parameter mandatory for function queue_scrub_stripe() btrfs: get correct owning_root when dropping snapshot btrfs: zoned: wait for data BG to be finished on direct IO allocation btrfs: zoned: drop no longer valid write pointer check btrfs: directly return 0 on no error code in btrfs_insert_raid_extent() btrfs: use u64 for buffer sizes in the tree search ioctls
2 parents 58c09ca + d393315 commit 9bacdd8

12 files changed

Lines changed: 69 additions & 41 deletions

File tree

fs/btrfs/ctree.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -432,7 +432,7 @@ static noinline int update_ref_for_cow(struct btrfs_trans_handle *trans,
432432
if (btrfs_block_can_be_shared(trans, root, buf)) {
433433
ret = btrfs_lookup_extent_info(trans, fs_info, buf->start,
434434
btrfs_header_level(buf), 1,
435-
&refs, &flags);
435+
&refs, &flags, NULL);
436436
if (ret)
437437
return ret;
438438
if (unlikely(refs == 0)) {

fs/btrfs/delayed-ref.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1041,7 +1041,7 @@ int btrfs_add_delayed_tree_ref(struct btrfs_trans_handle *trans,
10411041
return -ENOMEM;
10421042
}
10431043

1044-
if (btrfs_qgroup_enabled(fs_info) && !generic_ref->skip_qgroup) {
1044+
if (btrfs_qgroup_full_accounting(fs_info) && !generic_ref->skip_qgroup) {
10451045
record = kzalloc(sizeof(*record), GFP_NOFS);
10461046
if (!record) {
10471047
kmem_cache_free(btrfs_delayed_tree_ref_cachep, ref);
@@ -1144,7 +1144,7 @@ int btrfs_add_delayed_data_ref(struct btrfs_trans_handle *trans,
11441144
return -ENOMEM;
11451145
}
11461146

1147-
if (btrfs_qgroup_enabled(fs_info) && !generic_ref->skip_qgroup) {
1147+
if (btrfs_qgroup_full_accounting(fs_info) && !generic_ref->skip_qgroup) {
11481148
record = kzalloc(sizeof(*record), GFP_NOFS);
11491149
if (!record) {
11501150
kmem_cache_free(btrfs_delayed_data_ref_cachep, ref);

fs/btrfs/extent-tree.c

Lines changed: 17 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -102,7 +102,8 @@ int btrfs_lookup_data_extent(struct btrfs_fs_info *fs_info, u64 start, u64 len)
102102
*/
103103
int btrfs_lookup_extent_info(struct btrfs_trans_handle *trans,
104104
struct btrfs_fs_info *fs_info, u64 bytenr,
105-
u64 offset, int metadata, u64 *refs, u64 *flags)
105+
u64 offset, int metadata, u64 *refs, u64 *flags,
106+
u64 *owning_root)
106107
{
107108
struct btrfs_root *extent_root;
108109
struct btrfs_delayed_ref_head *head;
@@ -114,6 +115,7 @@ int btrfs_lookup_extent_info(struct btrfs_trans_handle *trans,
114115
u32 item_size;
115116
u64 num_refs;
116117
u64 extent_flags;
118+
u64 owner = 0;
117119
int ret;
118120

119121
/*
@@ -167,6 +169,8 @@ int btrfs_lookup_extent_info(struct btrfs_trans_handle *trans,
167169
struct btrfs_extent_item);
168170
num_refs = btrfs_extent_refs(leaf, ei);
169171
extent_flags = btrfs_extent_flags(leaf, ei);
172+
owner = btrfs_get_extent_owner_root(fs_info, leaf,
173+
path->slots[0]);
170174
} else {
171175
ret = -EUCLEAN;
172176
btrfs_err(fs_info,
@@ -226,6 +230,8 @@ int btrfs_lookup_extent_info(struct btrfs_trans_handle *trans,
226230
*refs = num_refs;
227231
if (flags)
228232
*flags = extent_flags;
233+
if (owning_root)
234+
*owning_root = owner;
229235
out_free:
230236
btrfs_free_path(path);
231237
return ret;
@@ -5234,7 +5240,7 @@ static noinline void reada_walk_down(struct btrfs_trans_handle *trans,
52345240
/* We don't lock the tree block, it's OK to be racy here */
52355241
ret = btrfs_lookup_extent_info(trans, fs_info, bytenr,
52365242
wc->level - 1, 1, &refs,
5237-
&flags);
5243+
&flags, NULL);
52385244
/* We don't care about errors in readahead. */
52395245
if (ret < 0)
52405246
continue;
@@ -5301,7 +5307,8 @@ static noinline int walk_down_proc(struct btrfs_trans_handle *trans,
53015307
ret = btrfs_lookup_extent_info(trans, fs_info,
53025308
eb->start, level, 1,
53035309
&wc->refs[level],
5304-
&wc->flags[level]);
5310+
&wc->flags[level],
5311+
NULL);
53055312
BUG_ON(ret == -ENOMEM);
53065313
if (ret)
53075314
return ret;
@@ -5391,6 +5398,7 @@ static noinline int do_walk_down(struct btrfs_trans_handle *trans,
53915398
u64 bytenr;
53925399
u64 generation;
53935400
u64 parent;
5401+
u64 owner_root = 0;
53945402
struct btrfs_tree_parent_check check = { 0 };
53955403
struct btrfs_key key;
53965404
struct btrfs_ref ref = { 0 };
@@ -5434,7 +5442,8 @@ static noinline int do_walk_down(struct btrfs_trans_handle *trans,
54345442

54355443
ret = btrfs_lookup_extent_info(trans, fs_info, bytenr, level - 1, 1,
54365444
&wc->refs[level - 1],
5437-
&wc->flags[level - 1]);
5445+
&wc->flags[level - 1],
5446+
&owner_root);
54385447
if (ret < 0)
54395448
goto out_unlock;
54405449

@@ -5567,8 +5576,7 @@ static noinline int do_walk_down(struct btrfs_trans_handle *trans,
55675576
find_next_key(path, level, &wc->drop_progress);
55685577

55695578
btrfs_init_generic_ref(&ref, BTRFS_DROP_DELAYED_REF, bytenr,
5570-
fs_info->nodesize, parent,
5571-
btrfs_header_owner(next));
5579+
fs_info->nodesize, parent, owner_root);
55725580
btrfs_init_tree_ref(&ref, level - 1, root->root_key.objectid,
55735581
0, false);
55745582
ret = btrfs_free_extent(trans, &ref);
@@ -5635,7 +5643,8 @@ static noinline int walk_up_proc(struct btrfs_trans_handle *trans,
56355643
ret = btrfs_lookup_extent_info(trans, fs_info,
56365644
eb->start, level, 1,
56375645
&wc->refs[level],
5638-
&wc->flags[level]);
5646+
&wc->flags[level],
5647+
NULL);
56395648
if (ret < 0) {
56405649
btrfs_tree_unlock_rw(eb, path->locks[level]);
56415650
path->locks[level] = 0;
@@ -5880,7 +5889,7 @@ int btrfs_drop_snapshot(struct btrfs_root *root, int update_ref, int for_reloc)
58805889
ret = btrfs_lookup_extent_info(trans, fs_info,
58815890
path->nodes[level]->start,
58825891
level, 1, &wc->refs[level],
5883-
&wc->flags[level]);
5892+
&wc->flags[level], NULL);
58845893
if (ret < 0) {
58855894
err = ret;
58865895
goto out_end_trans;

fs/btrfs/extent-tree.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -99,7 +99,8 @@ u64 btrfs_cleanup_ref_head_accounting(struct btrfs_fs_info *fs_info,
9999
int btrfs_lookup_data_extent(struct btrfs_fs_info *fs_info, u64 start, u64 len);
100100
int btrfs_lookup_extent_info(struct btrfs_trans_handle *trans,
101101
struct btrfs_fs_info *fs_info, u64 bytenr,
102-
u64 offset, int metadata, u64 *refs, u64 *flags);
102+
u64 offset, int metadata, u64 *refs, u64 *flags,
103+
u64 *owner_root);
103104
int btrfs_pin_extent(struct btrfs_trans_handle *trans, u64 bytenr, u64 num,
104105
int reserved);
105106
int btrfs_pin_extent_for_log_replay(struct btrfs_trans_handle *trans,

fs/btrfs/inode.c

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6983,8 +6983,15 @@ static struct extent_map *btrfs_new_extent_direct(struct btrfs_inode *inode,
69836983
int ret;
69846984

69856985
alloc_hint = get_extent_allocation_hint(inode, start, len);
6986+
again:
69866987
ret = btrfs_reserve_extent(root, len, len, fs_info->sectorsize,
69876988
0, alloc_hint, &ins, 1, 1);
6989+
if (ret == -EAGAIN) {
6990+
ASSERT(btrfs_is_zoned(fs_info));
6991+
wait_on_bit_io(&inode->root->fs_info->flags, BTRFS_FS_NEED_ZONE_FINISH,
6992+
TASK_UNINTERRUPTIBLE);
6993+
goto again;
6994+
}
69886995
if (ret)
69896996
return ERR_PTR(ret);
69906997

fs/btrfs/ioctl.c

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1528,7 +1528,7 @@ static noinline int key_in_sk(struct btrfs_key *key,
15281528
static noinline int copy_to_sk(struct btrfs_path *path,
15291529
struct btrfs_key *key,
15301530
struct btrfs_ioctl_search_key *sk,
1531-
size_t *buf_size,
1531+
u64 *buf_size,
15321532
char __user *ubuf,
15331533
unsigned long *sk_offset,
15341534
int *num_found)
@@ -1660,7 +1660,7 @@ static noinline int copy_to_sk(struct btrfs_path *path,
16601660

16611661
static noinline int search_ioctl(struct inode *inode,
16621662
struct btrfs_ioctl_search_key *sk,
1663-
size_t *buf_size,
1663+
u64 *buf_size,
16641664
char __user *ubuf)
16651665
{
16661666
struct btrfs_fs_info *info = btrfs_sb(inode->i_sb);
@@ -1733,7 +1733,7 @@ static noinline int btrfs_ioctl_tree_search(struct inode *inode,
17331733
struct btrfs_ioctl_search_args __user *uargs = argp;
17341734
struct btrfs_ioctl_search_key sk;
17351735
int ret;
1736-
size_t buf_size;
1736+
u64 buf_size;
17371737

17381738
if (!capable(CAP_SYS_ADMIN))
17391739
return -EPERM;
@@ -1763,8 +1763,8 @@ static noinline int btrfs_ioctl_tree_search_v2(struct inode *inode,
17631763
struct btrfs_ioctl_search_args_v2 __user *uarg = argp;
17641764
struct btrfs_ioctl_search_args_v2 args;
17651765
int ret;
1766-
size_t buf_size;
1767-
const size_t buf_limit = SZ_16M;
1766+
u64 buf_size;
1767+
const u64 buf_limit = SZ_16M;
17681768

17691769
if (!capable(CAP_SYS_ADMIN))
17701770
return -EPERM;

fs/btrfs/qgroup.c

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1888,7 +1888,7 @@ int btrfs_qgroup_trace_extent_nolock(struct btrfs_fs_info *fs_info,
18881888
u64 bytenr = record->bytenr;
18891889

18901890
if (!btrfs_qgroup_full_accounting(fs_info))
1891-
return 0;
1891+
return 1;
18921892

18931893
lockdep_assert_held(&delayed_refs->lock);
18941894
trace_btrfs_qgroup_trace_extent(fs_info, record);
@@ -2874,13 +2874,19 @@ int btrfs_qgroup_account_extent(struct btrfs_trans_handle *trans, u64 bytenr,
28742874
qgroup_update_counters(fs_info, &qgroups, nr_old_roots, nr_new_roots,
28752875
num_bytes, seq);
28762876

2877+
/*
2878+
* We're done using the iterator, release all its qgroups while holding
2879+
* fs_info->qgroup_lock so that we don't race with btrfs_remove_qgroup()
2880+
* and trigger use-after-free accesses to qgroups.
2881+
*/
2882+
qgroup_iterator_nested_clean(&qgroups);
2883+
28772884
/*
28782885
* Bump qgroup_seq to avoid seq overlap
28792886
*/
28802887
fs_info->qgroup_seq += max(nr_old_roots, nr_new_roots) + 1;
28812888
spin_unlock(&fs_info->qgroup_lock);
28822889
out_free:
2883-
qgroup_iterator_nested_clean(&qgroups);
28842890
ulist_free(old_roots);
28852891
ulist_free(new_roots);
28862892
return ret;

fs/btrfs/raid-stripe-tree.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -145,7 +145,7 @@ int btrfs_insert_raid_extent(struct btrfs_trans_handle *trans,
145145
btrfs_put_bioc(bioc);
146146
}
147147

148-
return ret;
148+
return 0;
149149
}
150150

151151
int btrfs_get_raid_extent_offset(struct btrfs_fs_info *fs_info,

fs/btrfs/scrub.c

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1868,6 +1868,9 @@ static int queue_scrub_stripe(struct scrub_ctx *sctx, struct btrfs_block_group *
18681868
*/
18691869
ASSERT(sctx->cur_stripe < SCRUB_TOTAL_STRIPES);
18701870

1871+
/* @found_logical_ret must be specified. */
1872+
ASSERT(found_logical_ret);
1873+
18711874
stripe = &sctx->stripes[sctx->cur_stripe];
18721875
scrub_reset_stripe(stripe);
18731876
ret = scrub_find_fill_first_stripe(bg, &sctx->extent_path,
@@ -1876,8 +1879,7 @@ static int queue_scrub_stripe(struct scrub_ctx *sctx, struct btrfs_block_group *
18761879
/* Either >0 as no more extents or <0 for error. */
18771880
if (ret)
18781881
return ret;
1879-
if (found_logical_ret)
1880-
*found_logical_ret = stripe->logical;
1882+
*found_logical_ret = stripe->logical;
18811883
sctx->cur_stripe++;
18821884

18831885
/* We filled one group, submit it. */
@@ -2080,7 +2082,7 @@ static int scrub_simple_mirror(struct scrub_ctx *sctx,
20802082

20812083
/* Go through each extent items inside the logical range */
20822084
while (cur_logical < logical_end) {
2083-
u64 found_logical;
2085+
u64 found_logical = U64_MAX;
20842086
u64 cur_physical = physical + cur_logical - logical_start;
20852087

20862088
/* Canceled? */
@@ -2115,6 +2117,8 @@ static int scrub_simple_mirror(struct scrub_ctx *sctx,
21152117
if (ret < 0)
21162118
break;
21172119

2120+
/* queue_scrub_stripe() returned 0, @found_logical must be updated. */
2121+
ASSERT(found_logical != U64_MAX);
21182122
cur_logical = found_logical + BTRFS_STRIPE_LEN;
21192123

21202124
/* Don't hold CPU for too long time */

fs/btrfs/volumes.c

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -748,13 +748,13 @@ static noinline struct btrfs_device *device_list_add(const char *path,
748748

749749
if (!fs_devices) {
750750
fs_devices = alloc_fs_devices(disk_super->fsid);
751+
if (IS_ERR(fs_devices))
752+
return ERR_CAST(fs_devices);
753+
751754
if (has_metadata_uuid)
752755
memcpy(fs_devices->metadata_uuid,
753756
disk_super->metadata_uuid, BTRFS_FSID_SIZE);
754757

755-
if (IS_ERR(fs_devices))
756-
return ERR_CAST(fs_devices);
757-
758758
if (same_fsid_diff_dev) {
759759
generate_random_uuid(fs_devices->fsid);
760760
fs_devices->temp_fsid = true;

0 commit comments

Comments
 (0)