Skip to content

Commit 2840526

Browse files
committed
Merge tag 'for-6.11-rc5-tag' of git://git.kernel.org/pub/scm/linux/kernel/git/kdave/linux
Pull btrfs fixes from David Sterba: - fix use-after-free when submitting bios for read, after an error and partially submitted bio the original one is freed while it can be still be accessed again - fix fstests case btrfs/301, with enabled quotas wait for delayed iputs when flushing delalloc - fix periodic block group reclaim, an unitialized value can be returned if there are no block groups to reclaim - fix build warning (-Wmaybe-uninitialized) * tag 'for-6.11-rc5-tag' of git://git.kernel.org/pub/scm/linux/kernel/git/kdave/linux: btrfs: fix uninitialized return value from btrfs_reclaim_sweep() btrfs: fix a use-after-free when hitting errors inside btrfs_submit_chunk() btrfs: initialize last_extent_end to fix -Wmaybe-uninitialized warning in extent_fiemap() btrfs: run delayed iputs when flushing delalloc
2 parents 86987d8 + ecb5427 commit 2840526

5 files changed

Lines changed: 27 additions & 22 deletions

File tree

fs/btrfs/bio.c

Lines changed: 18 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -668,7 +668,6 @@ static bool btrfs_submit_chunk(struct btrfs_bio *bbio, int mirror_num)
668668
{
669669
struct btrfs_inode *inode = bbio->inode;
670670
struct btrfs_fs_info *fs_info = bbio->fs_info;
671-
struct btrfs_bio *orig_bbio = bbio;
672671
struct bio *bio = &bbio->bio;
673672
u64 logical = bio->bi_iter.bi_sector << SECTOR_SHIFT;
674673
u64 length = bio->bi_iter.bi_size;
@@ -706,7 +705,7 @@ static bool btrfs_submit_chunk(struct btrfs_bio *bbio, int mirror_num)
706705
bbio->saved_iter = bio->bi_iter;
707706
ret = btrfs_lookup_bio_sums(bbio);
708707
if (ret)
709-
goto fail_put_bio;
708+
goto fail;
710709
}
711710

712711
if (btrfs_op(bio) == BTRFS_MAP_WRITE) {
@@ -740,26 +739,37 @@ static bool btrfs_submit_chunk(struct btrfs_bio *bbio, int mirror_num)
740739

741740
ret = btrfs_bio_csum(bbio);
742741
if (ret)
743-
goto fail_put_bio;
742+
goto fail;
744743
} else if (use_append ||
745744
(btrfs_is_zoned(fs_info) && inode &&
746745
inode->flags & BTRFS_INODE_NODATASUM)) {
747746
ret = btrfs_alloc_dummy_sum(bbio);
748747
if (ret)
749-
goto fail_put_bio;
748+
goto fail;
750749
}
751750
}
752751

753752
__btrfs_submit_bio(bio, bioc, &smap, mirror_num);
754753
done:
755754
return map_length == length;
756755

757-
fail_put_bio:
758-
if (map_length < length)
759-
btrfs_cleanup_bio(bbio);
760756
fail:
761757
btrfs_bio_counter_dec(fs_info);
762-
btrfs_bio_end_io(orig_bbio, ret);
758+
/*
759+
* We have split the original bbio, now we have to end both the current
760+
* @bbio and remaining one, as the remaining one will never be submitted.
761+
*/
762+
if (map_length < length) {
763+
struct btrfs_bio *remaining = bbio->private;
764+
765+
ASSERT(bbio->bio.bi_pool == &btrfs_clone_bioset);
766+
ASSERT(remaining);
767+
768+
remaining->bio.bi_status = ret;
769+
btrfs_orig_bbio_end_io(remaining);
770+
}
771+
bbio->bio.bi_status = ret;
772+
btrfs_orig_bbio_end_io(bbio);
763773
/* Do not submit another chunk */
764774
return true;
765775
}

fs/btrfs/fiemap.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -637,7 +637,7 @@ static int extent_fiemap(struct btrfs_inode *inode,
637637
struct btrfs_path *path;
638638
struct fiemap_cache cache = { 0 };
639639
struct btrfs_backref_share_check_ctx *backref_ctx;
640-
u64 last_extent_end;
640+
u64 last_extent_end = 0;
641641
u64 prev_extent_end;
642642
u64 range_start;
643643
u64 range_end;

fs/btrfs/qgroup.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4185,6 +4185,8 @@ static int try_flush_qgroup(struct btrfs_root *root)
41854185
return 0;
41864186
}
41874187

4188+
btrfs_run_delayed_iputs(root->fs_info);
4189+
btrfs_wait_on_delayed_iputs(root->fs_info);
41884190
ret = btrfs_start_delalloc_snapshot(root, true);
41894191
if (ret < 0)
41904192
goto out;

fs/btrfs/space-info.c

Lines changed: 5 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1985,8 +1985,8 @@ static bool is_reclaim_urgent(struct btrfs_space_info *space_info)
19851985
return unalloc < data_chunk_size;
19861986
}
19871987

1988-
static int do_reclaim_sweep(struct btrfs_fs_info *fs_info,
1989-
struct btrfs_space_info *space_info, int raid)
1988+
static void do_reclaim_sweep(struct btrfs_fs_info *fs_info,
1989+
struct btrfs_space_info *space_info, int raid)
19901990
{
19911991
struct btrfs_block_group *bg;
19921992
int thresh_pct;
@@ -2031,7 +2031,6 @@ static int do_reclaim_sweep(struct btrfs_fs_info *fs_info,
20312031
}
20322032

20332033
up_read(&space_info->groups_sem);
2034-
return 0;
20352034
}
20362035

20372036
void btrfs_space_info_update_reclaimable(struct btrfs_space_info *space_info, s64 bytes)
@@ -2074,21 +2073,15 @@ bool btrfs_should_periodic_reclaim(struct btrfs_space_info *space_info)
20742073
return ret;
20752074
}
20762075

2077-
int btrfs_reclaim_sweep(struct btrfs_fs_info *fs_info)
2076+
void btrfs_reclaim_sweep(struct btrfs_fs_info *fs_info)
20782077
{
2079-
int ret;
20802078
int raid;
20812079
struct btrfs_space_info *space_info;
20822080

20832081
list_for_each_entry(space_info, &fs_info->space_info, list) {
20842082
if (!btrfs_should_periodic_reclaim(space_info))
20852083
continue;
2086-
for (raid = 0; raid < BTRFS_NR_RAID_TYPES; raid++) {
2087-
ret = do_reclaim_sweep(fs_info, space_info, raid);
2088-
if (ret)
2089-
return ret;
2090-
}
2084+
for (raid = 0; raid < BTRFS_NR_RAID_TYPES; raid++)
2085+
do_reclaim_sweep(fs_info, space_info, raid);
20912086
}
2092-
2093-
return ret;
20942087
}

fs/btrfs/space-info.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -294,6 +294,6 @@ void btrfs_space_info_update_reclaimable(struct btrfs_space_info *space_info, s6
294294
void btrfs_set_periodic_reclaim_ready(struct btrfs_space_info *space_info, bool ready);
295295
bool btrfs_should_periodic_reclaim(struct btrfs_space_info *space_info);
296296
int btrfs_calc_reclaim_threshold(struct btrfs_space_info *space_info);
297-
int btrfs_reclaim_sweep(struct btrfs_fs_info *fs_info);
297+
void btrfs_reclaim_sweep(struct btrfs_fs_info *fs_info);
298298

299299
#endif /* BTRFS_SPACE_INFO_H */

0 commit comments

Comments
 (0)