Skip to content

Commit 89b798a

Browse files
lorddoskiaskdave
authored andcommitted
btrfs: Use btrfs_get_io_geometry appropriately
Presently btrfs_map_block is used not only to do everything necessary to map a bio to the underlying allocation profile but it's also used to identify how much data could be written based on btrfs' stripe logic without actually submitting anything. This is achieved by passing NULL for 'bbio_ret' parameter. This patch refactors all callers that require just the mapping length by switching them to using btrfs_io_geometry instead of calling btrfs_map_block with a special NULL value for 'bbio_ret'. No functional change. Signed-off-by: Nikolay Borisov <[email protected]> Reviewed-by: David Sterba <[email protected]> Signed-off-by: David Sterba <[email protected]>
1 parent 5f14112 commit 89b798a

File tree

3 files changed

+30
-78
lines changed

3 files changed

+30
-78
lines changed

fs/btrfs/inode.c

Lines changed: 14 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1932,17 +1932,19 @@ int btrfs_bio_fits_in_stripe(struct page *page, size_t size, struct bio *bio,
19321932
u64 length = 0;
19331933
u64 map_length;
19341934
int ret;
1935+
struct btrfs_io_geometry geom;
19351936

19361937
if (bio_flags & EXTENT_BIO_COMPRESSED)
19371938
return 0;
19381939

19391940
length = bio->bi_iter.bi_size;
19401941
map_length = length;
1941-
ret = btrfs_map_block(fs_info, btrfs_op(bio), logical, &map_length,
1942-
NULL, 0);
1942+
ret = btrfs_get_io_geometry(fs_info, btrfs_op(bio), logical, map_length,
1943+
&geom);
19431944
if (ret < 0)
19441945
return ret;
1945-
if (map_length < length + size)
1946+
1947+
if (geom.len < length + size)
19461948
return 1;
19471949
return 0;
19481950
}
@@ -8308,22 +8310,21 @@ static int btrfs_submit_direct_hook(struct btrfs_dio_private *dip)
83088310
struct bio *orig_bio = dip->orig_bio;
83098311
u64 start_sector = orig_bio->bi_iter.bi_sector;
83108312
u64 file_offset = dip->logical_offset;
8311-
u64 map_length;
83128313
int async_submit = 0;
83138314
u64 submit_len;
83148315
int clone_offset = 0;
83158316
int clone_len;
83168317
int ret;
83178318
blk_status_t status;
8319+
struct btrfs_io_geometry geom;
83188320

8319-
map_length = orig_bio->bi_iter.bi_size;
8320-
submit_len = map_length;
8321-
ret = btrfs_map_block(fs_info, btrfs_op(orig_bio), start_sector << 9,
8322-
&map_length, NULL, 0);
8321+
submit_len = orig_bio->bi_iter.bi_size;
8322+
ret = btrfs_get_io_geometry(fs_info, btrfs_op(orig_bio),
8323+
start_sector << 9, submit_len, &geom);
83238324
if (ret)
83248325
return -EIO;
83258326

8326-
if (map_length >= submit_len) {
8327+
if (geom.len >= submit_len) {
83278328
bio = orig_bio;
83288329
dip->flags |= BTRFS_DIO_ORIG_BIO_SUBMITTED;
83298330
goto submit;
@@ -8336,10 +8337,10 @@ static int btrfs_submit_direct_hook(struct btrfs_dio_private *dip)
83368337
async_submit = 1;
83378338

83388339
/* bio split */
8339-
ASSERT(map_length <= INT_MAX);
8340+
ASSERT(geom.len <= INT_MAX);
83408341
atomic_inc(&dip->pending_bios);
83418342
do {
8342-
clone_len = min_t(int, submit_len, map_length);
8343+
clone_len = min_t(int, submit_len, geom.len);
83438344

83448345
/*
83458346
* This will never fail as it's passing GPF_NOFS and
@@ -8376,9 +8377,8 @@ static int btrfs_submit_direct_hook(struct btrfs_dio_private *dip)
83768377
start_sector += clone_len >> 9;
83778378
file_offset += clone_len;
83788379

8379-
map_length = submit_len;
8380-
ret = btrfs_map_block(fs_info, btrfs_op(orig_bio),
8381-
start_sector << 9, &map_length, NULL, 0);
8380+
ret = btrfs_get_io_geometry(fs_info, btrfs_op(orig_bio),
8381+
start_sector << 9, submit_len, &geom);
83828382
if (ret)
83838383
goto out_err;
83848384
} while (submit_len > 0);

fs/btrfs/volumes.c

Lines changed: 15 additions & 63 deletions
Original file line numberDiff line numberDiff line change
@@ -5930,7 +5930,7 @@ static bool need_full_stripe(enum btrfs_map_op op)
59305930
* usually shouldn't happen unless @logical is corrupted, 0 otherwise.
59315931
*/
59325932
int btrfs_get_io_geometry(struct btrfs_fs_info *fs_info, enum btrfs_map_op op,
5933-
u64 logical, u64 len, struct btrfs_io_geometry *io_geom)
5933+
u64 logical, u64 len, struct btrfs_io_geometry *io_geom)
59345934
{
59355935
struct extent_map *em;
59365936
struct map_lookup *map;
@@ -6037,78 +6037,30 @@ static int __btrfs_map_block(struct btrfs_fs_info *fs_info,
60376037
int patch_the_first_stripe_for_dev_replace = 0;
60386038
u64 physical_to_patch_in_first_stripe = 0;
60396039
u64 raid56_full_stripe_start = (u64)-1;
6040+
struct btrfs_io_geometry geom;
6041+
6042+
ASSERT(bbio_ret);
60406043

60416044
if (op == BTRFS_MAP_DISCARD)
60426045
return __btrfs_map_block_for_discard(fs_info, logical,
60436046
*length, bbio_ret);
60446047

6045-
em = btrfs_get_chunk_map(fs_info, logical, *length);
6046-
if (IS_ERR(em))
6047-
return PTR_ERR(em);
6048+
ret = btrfs_get_io_geometry(fs_info, op, logical, *length, &geom);
6049+
if (ret < 0)
6050+
return ret;
60486051

6052+
em = btrfs_get_chunk_map(fs_info, logical, *length);
6053+
ASSERT(em);
60496054
map = em->map_lookup;
6050-
offset = logical - em->start;
60516055

6052-
stripe_len = map->stripe_len;
6053-
stripe_nr = offset;
6054-
/*
6055-
* stripe_nr counts the total number of stripes we have to stride
6056-
* to get to this block
6057-
*/
6058-
stripe_nr = div64_u64(stripe_nr, stripe_len);
6056+
*length = geom.len;
6057+
offset = geom.offset;
6058+
stripe_len = geom.stripe_len;
6059+
stripe_nr = geom.stripe_nr;
6060+
stripe_offset = geom.stripe_offset;
6061+
raid56_full_stripe_start = geom.raid56_stripe_offset;
60596062
data_stripes = nr_data_stripes(map);
60606063

6061-
stripe_offset = stripe_nr * stripe_len;
6062-
if (offset < stripe_offset) {
6063-
btrfs_crit(fs_info,
6064-
"stripe math has gone wrong, stripe_offset=%llu, offset=%llu, start=%llu, logical=%llu, stripe_len=%llu",
6065-
stripe_offset, offset, em->start, logical,
6066-
stripe_len);
6067-
free_extent_map(em);
6068-
return -EINVAL;
6069-
}
6070-
6071-
/* stripe_offset is the offset of this block in its stripe*/
6072-
stripe_offset = offset - stripe_offset;
6073-
6074-
/* if we're here for raid56, we need to know the stripe aligned start */
6075-
if (map->type & BTRFS_BLOCK_GROUP_RAID56_MASK) {
6076-
unsigned long full_stripe_len = stripe_len * data_stripes;
6077-
raid56_full_stripe_start = offset;
6078-
6079-
/* allow a write of a full stripe, but make sure we don't
6080-
* allow straddling of stripes
6081-
*/
6082-
raid56_full_stripe_start = div64_u64(raid56_full_stripe_start,
6083-
full_stripe_len);
6084-
raid56_full_stripe_start *= full_stripe_len;
6085-
}
6086-
6087-
if (map->type & BTRFS_BLOCK_GROUP_PROFILE_MASK) {
6088-
u64 max_len;
6089-
/* For writes to RAID[56], allow a full stripeset across all disks.
6090-
For other RAID types and for RAID[56] reads, just allow a single
6091-
stripe (on a single disk). */
6092-
if ((map->type & BTRFS_BLOCK_GROUP_RAID56_MASK) &&
6093-
(op == BTRFS_MAP_WRITE)) {
6094-
max_len = stripe_len * data_stripes -
6095-
(offset - raid56_full_stripe_start);
6096-
} else {
6097-
/* we limit the length of each bio to what fits in a stripe */
6098-
max_len = stripe_len - stripe_offset;
6099-
}
6100-
*length = min_t(u64, em->len - offset, max_len);
6101-
} else {
6102-
*length = em->len - offset;
6103-
}
6104-
6105-
/*
6106-
* This is for when we're called from btrfs_bio_fits_in_stripe and all
6107-
* it cares about is the length
6108-
*/
6109-
if (!bbio_ret)
6110-
goto out;
6111-
61126064
down_read(&dev_replace->rwsem);
61136065
dev_replace_is_ongoing = btrfs_dev_replace_is_ongoing(dev_replace);
61146066
/*

fs/btrfs/volumes.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -429,7 +429,7 @@ int btrfs_map_sblock(struct btrfs_fs_info *fs_info, enum btrfs_map_op op,
429429
u64 logical, u64 *length,
430430
struct btrfs_bio **bbio_ret);
431431
int btrfs_get_io_geometry(struct btrfs_fs_info *fs_info, enum btrfs_map_op op,
432-
u64 logical, u64 len, struct btrfs_io_geometry *io_geom);
432+
u64 logical, u64 len, struct btrfs_io_geometry *io_geom);
433433
int btrfs_rmap_block(struct btrfs_fs_info *fs_info, u64 chunk_start,
434434
u64 physical, u64 **logical, int *naddrs, int *stripe_len);
435435
int btrfs_read_sys_array(struct btrfs_fs_info *fs_info);

0 commit comments

Comments
 (0)