Skip to content

Commit 8991448

Browse files
committed
Merge tag 'for-7.0-rc4-tag' of git://git.kernel.org/pub/scm/linux/kernel/git/kdave/linux
Pull btrfs fixes from David Sterba: "Another batch of fixes for problems that have been identified by tools analyzing code or by fuzzing. Most of them are short, two patches fix the same thing in many places so the diffs are bigger. - handle potential NULL pointer errors after attempting to read extent and checksum trees - prevent ENOSPC when creating many qgroups by ioctls in the same transaction - encoded write ioctl fixes (with 64K page and 4K block size): - fix unexpected bio length - do not let compressed bios and pages interfere with page cache - compression fixes on setups with 64K page and 4K block size: fix folio length assertions (zstd and lzo) - remap tree fixes: - make sure to hold block group reference while moving it - handle early exit when moving block group to unused list - handle deleted subvolumes with inconsistent state of deletion progress" * tag 'for-7.0-rc4-tag' of git://git.kernel.org/pub/scm/linux/kernel/git/kdave/linux: btrfs: reject root items with drop_progress and zero drop_level btrfs: check block group before marking it unused in balance_remap_chunks() btrfs: hold block group reference during entire move_existing_remap() btrfs: fix an incorrect ASSERT() condition inside lzo_decompress_bio() btrfs: fix an incorrect ASSERT() condition inside zstd_decompress_bio() btrfs: do not touch page cache for encoded writes btrfs: fix a bug that makes encoded write bio larger than expected btrfs: reserve enough transaction items for qgroup ioctls btrfs: check for NULL root after calls to btrfs_csum_root() btrfs: check for NULL root after calls to btrfs_extent_root()
2 parents a0c8317 + b17b79f commit 8991448

18 files changed

Lines changed: 341 additions & 40 deletions

fs/btrfs/backref.c

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1393,6 +1393,13 @@ static int find_parent_nodes(struct btrfs_backref_walk_ctx *ctx,
13931393
.indirect_missing_keys = PREFTREE_INIT
13941394
};
13951395

1396+
if (unlikely(!root)) {
1397+
btrfs_err(ctx->fs_info,
1398+
"missing extent root for extent at bytenr %llu",
1399+
ctx->bytenr);
1400+
return -EUCLEAN;
1401+
}
1402+
13961403
/* Roots ulist is not needed when using a sharedness check context. */
13971404
if (sc)
13981405
ASSERT(ctx->roots == NULL);
@@ -2204,6 +2211,13 @@ int extent_from_logical(struct btrfs_fs_info *fs_info, u64 logical,
22042211
struct btrfs_extent_item *ei;
22052212
struct btrfs_key key;
22062213

2214+
if (unlikely(!extent_root)) {
2215+
btrfs_err(fs_info,
2216+
"missing extent root for extent at bytenr %llu",
2217+
logical);
2218+
return -EUCLEAN;
2219+
}
2220+
22072221
key.objectid = logical;
22082222
if (btrfs_fs_incompat(fs_info, SKINNY_METADATA))
22092223
key.type = BTRFS_METADATA_ITEM_KEY;
@@ -2851,6 +2865,13 @@ int btrfs_backref_iter_start(struct btrfs_backref_iter *iter, u64 bytenr)
28512865
struct btrfs_key key;
28522866
int ret;
28532867

2868+
if (unlikely(!extent_root)) {
2869+
btrfs_err(fs_info,
2870+
"missing extent root for extent at bytenr %llu",
2871+
bytenr);
2872+
return -EUCLEAN;
2873+
}
2874+
28542875
key.objectid = bytenr;
28552876
key.type = BTRFS_METADATA_ITEM_KEY;
28562877
key.offset = (u64)-1;
@@ -2987,6 +3008,13 @@ int btrfs_backref_iter_next(struct btrfs_backref_iter *iter)
29873008

29883009
/* We're at keyed items, there is no inline item, go to the next one */
29893010
extent_root = btrfs_extent_root(iter->fs_info, iter->bytenr);
3011+
if (unlikely(!extent_root)) {
3012+
btrfs_err(iter->fs_info,
3013+
"missing extent root for extent at bytenr %llu",
3014+
iter->bytenr);
3015+
return -EUCLEAN;
3016+
}
3017+
29903018
ret = btrfs_next_item(extent_root, iter->path);
29913019
if (ret)
29923020
return ret;

fs/btrfs/block-group.c

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -739,6 +739,12 @@ static int load_extent_tree_free(struct btrfs_caching_control *caching_ctl)
739739

740740
last = max_t(u64, block_group->start, BTRFS_SUPER_INFO_OFFSET);
741741
extent_root = btrfs_extent_root(fs_info, last);
742+
if (unlikely(!extent_root)) {
743+
btrfs_err(fs_info,
744+
"missing extent root for block group at offset %llu",
745+
block_group->start);
746+
return -EUCLEAN;
747+
}
742748

743749
#ifdef CONFIG_BTRFS_DEBUG
744750
/*
@@ -1061,6 +1067,11 @@ static int remove_block_group_item(struct btrfs_trans_handle *trans,
10611067
int ret;
10621068

10631069
root = btrfs_block_group_root(fs_info);
1070+
if (unlikely(!root)) {
1071+
btrfs_err(fs_info, "missing block group root");
1072+
return -EUCLEAN;
1073+
}
1074+
10641075
key.objectid = block_group->start;
10651076
key.type = BTRFS_BLOCK_GROUP_ITEM_KEY;
10661077
key.offset = block_group->length;
@@ -1349,6 +1360,11 @@ struct btrfs_trans_handle *btrfs_start_trans_remove_block_group(
13491360
struct btrfs_chunk_map *map;
13501361
unsigned int num_items;
13511362

1363+
if (unlikely(!root)) {
1364+
btrfs_err(fs_info, "missing block group root");
1365+
return ERR_PTR(-EUCLEAN);
1366+
}
1367+
13521368
map = btrfs_find_chunk_map(fs_info, chunk_offset, 1);
13531369
ASSERT(map != NULL);
13541370
ASSERT(map->start == chunk_offset);
@@ -2140,6 +2156,11 @@ static int find_first_block_group(struct btrfs_fs_info *fs_info,
21402156
int ret;
21412157
struct btrfs_key found_key;
21422158

2159+
if (unlikely(!root)) {
2160+
btrfs_err(fs_info, "missing block group root");
2161+
return -EUCLEAN;
2162+
}
2163+
21432164
btrfs_for_each_slot(root, key, &found_key, path, ret) {
21442165
if (found_key.objectid >= key->objectid &&
21452166
found_key.type == BTRFS_BLOCK_GROUP_ITEM_KEY) {
@@ -2713,6 +2734,11 @@ static int insert_block_group_item(struct btrfs_trans_handle *trans,
27132734
size_t size;
27142735
int ret;
27152736

2737+
if (unlikely(!root)) {
2738+
btrfs_err(fs_info, "missing block group root");
2739+
return -EUCLEAN;
2740+
}
2741+
27162742
spin_lock(&block_group->lock);
27172743
btrfs_set_stack_block_group_v2_used(&bgi, block_group->used);
27182744
btrfs_set_stack_block_group_v2_chunk_objectid(&bgi, block_group->global_root_id);
@@ -3048,6 +3074,11 @@ int btrfs_inc_block_group_ro(struct btrfs_block_group *cache,
30483074
int ret;
30493075
bool dirty_bg_running;
30503076

3077+
if (unlikely(!root)) {
3078+
btrfs_err(fs_info, "missing block group root");
3079+
return -EUCLEAN;
3080+
}
3081+
30513082
/*
30523083
* This can only happen when we are doing read-only scrub on read-only
30533084
* mount.
@@ -3192,6 +3223,11 @@ static int update_block_group_item(struct btrfs_trans_handle *trans,
31923223
u64 used, remap_bytes;
31933224
u32 identity_remap_count;
31943225

3226+
if (unlikely(!root)) {
3227+
btrfs_err(fs_info, "missing block group root");
3228+
return -EUCLEAN;
3229+
}
3230+
31953231
/*
31963232
* Block group items update can be triggered out of commit transaction
31973233
* critical section, thus we need a consistent view of used bytes.

fs/btrfs/compression.c

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -320,10 +320,16 @@ void btrfs_submit_compressed_write(struct btrfs_ordered_extent *ordered,
320320

321321
ASSERT(IS_ALIGNED(ordered->file_offset, fs_info->sectorsize));
322322
ASSERT(IS_ALIGNED(ordered->num_bytes, fs_info->sectorsize));
323-
ASSERT(cb->writeback);
323+
/*
324+
* This flag determines if we should clear the writeback flag from the
325+
* page cache. But this function is only utilized by encoded writes, it
326+
* never goes through the page cache.
327+
*/
328+
ASSERT(!cb->writeback);
324329

325330
cb->start = ordered->file_offset;
326331
cb->len = ordered->num_bytes;
332+
ASSERT(cb->bbio.bio.bi_iter.bi_size == ordered->disk_num_bytes);
327333
cb->compressed_len = ordered->disk_num_bytes;
328334
cb->bbio.bio.bi_iter.bi_sector = ordered->disk_bytenr >> SECTOR_SHIFT;
329335
cb->bbio.ordered = ordered;
@@ -345,8 +351,7 @@ struct compressed_bio *btrfs_alloc_compressed_write(struct btrfs_inode *inode,
345351
cb = alloc_compressed_bio(inode, start, REQ_OP_WRITE, end_bbio_compressed_write);
346352
cb->start = start;
347353
cb->len = len;
348-
cb->writeback = true;
349-
354+
cb->writeback = false;
350355
return cb;
351356
}
352357

fs/btrfs/disk-io.c

Lines changed: 17 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1591,7 +1591,7 @@ static int find_newest_super_backup(struct btrfs_fs_info *info)
15911591
* this will bump the backup pointer by one when it is
15921592
* done
15931593
*/
1594-
static void backup_super_roots(struct btrfs_fs_info *info)
1594+
static int backup_super_roots(struct btrfs_fs_info *info)
15951595
{
15961596
const int next_backup = info->backup_root_index;
15971597
struct btrfs_root_backup *root_backup;
@@ -1623,6 +1623,15 @@ static void backup_super_roots(struct btrfs_fs_info *info)
16231623
struct btrfs_root *extent_root = btrfs_extent_root(info, 0);
16241624
struct btrfs_root *csum_root = btrfs_csum_root(info, 0);
16251625

1626+
if (unlikely(!extent_root)) {
1627+
btrfs_err(info, "missing extent root for extent at bytenr 0");
1628+
return -EUCLEAN;
1629+
}
1630+
if (unlikely(!csum_root)) {
1631+
btrfs_err(info, "missing csum root for extent at bytenr 0");
1632+
return -EUCLEAN;
1633+
}
1634+
16261635
btrfs_set_backup_extent_root(root_backup,
16271636
extent_root->node->start);
16281637
btrfs_set_backup_extent_root_gen(root_backup,
@@ -1670,6 +1679,8 @@ static void backup_super_roots(struct btrfs_fs_info *info)
16701679
memcpy(&info->super_copy->super_roots,
16711680
&info->super_for_commit->super_roots,
16721681
sizeof(*root_backup) * BTRFS_NUM_BACKUP_ROOTS);
1682+
1683+
return 0;
16731684
}
16741685

16751686
/*
@@ -4051,8 +4062,11 @@ int write_all_supers(struct btrfs_fs_info *fs_info, int max_mirrors)
40514062
* not from fsync where the tree roots in fs_info have not
40524063
* been consistent on disk.
40534064
*/
4054-
if (max_mirrors == 0)
4055-
backup_super_roots(fs_info);
4065+
if (max_mirrors == 0) {
4066+
ret = backup_super_roots(fs_info);
4067+
if (ret < 0)
4068+
return ret;
4069+
}
40564070

40574071
sb = fs_info->super_for_commit;
40584072
dev_item = &sb->dev_item;

0 commit comments

Comments
 (0)