summaryrefslogtreecommitdiff
path: root/fs/btrfs/inode.c
diff options
context:
space:
mode:
authorQu Wenruo <wqu@suse.com>2024-04-30 07:53:06 +0930
committerDavid Sterba <dsterba@suse.com>2024-07-11 15:33:21 +0200
commitc77a8c61002e91d859e118008fd495efbe1d9373 (patch)
treebdea6b735810f7e578aa2c34c54bd0adce08a25d /fs/btrfs/inode.c
parente28b851ed9b232c3b84cb8d0fedbdfa8ca881386 (diff)
btrfs: remove extent_map::block_start member
The member extent_map::block_start can be calculated from extent_map::disk_bytenr + extent_map::offset for regular extents. And otherwise just extent_map::disk_bytenr. And this is already validated by the validate_extent_map(). Now we can remove the member. However there is a special case in btrfs_create_dio_extent() where we for NOCOW/PREALLOC ordered extents cannot directly use the resulting btrfs_file_extent, as btrfs_split_ordered_extent() cannot handle them yet. So for that call site, we pass file_extent->disk_bytenr + file_extent->num_bytes as disk_bytenr for the ordered extent, and 0 for offset. Reviewed-by: Johannes Thumshirn <johannes.thumshirn@wdc.com> Reviewed-by: Filipe Manana <fdmanana@suse.com> Signed-off-by: Qu Wenruo <wqu@suse.com> Reviewed-by: David Sterba <dsterba@suse.com> Signed-off-by: David Sterba <dsterba@suse.com>
Diffstat (limited to 'fs/btrfs/inode.c')
-rw-r--r--fs/btrfs/inode.c79
1 files changed, 43 insertions, 36 deletions
diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c
index 974363b85175..26087cc3029f 100644
--- a/fs/btrfs/inode.c
+++ b/fs/btrfs/inode.c
@@ -139,7 +139,7 @@ static noinline int run_delalloc_cow(struct btrfs_inode *inode,
u64 end, struct writeback_control *wbc,
bool pages_dirty);
static struct extent_map *create_io_em(struct btrfs_inode *inode, u64 start,
- u64 len, u64 block_start,
+ u64 len,
u64 disk_num_bytes,
u64 ram_bytes, int compress_type,
const struct btrfs_file_extent *file_extent,
@@ -1210,7 +1210,6 @@ static void submit_one_async_extent(struct async_chunk *async_chunk,
em = create_io_em(inode, start,
async_extent->ram_size, /* len */
- ins.objectid, /* block_start */
ins.offset, /* orig_block_len */
async_extent->ram_size, /* ram_bytes */
async_extent->compress_type,
@@ -1288,15 +1287,15 @@ static u64 get_extent_allocation_hint(struct btrfs_inode *inode, u64 start,
* first block in this inode and use that as a hint. If that
* block is also bogus then just don't worry about it.
*/
- if (em->block_start >= EXTENT_MAP_LAST_BYTE) {
+ if (em->disk_bytenr >= EXTENT_MAP_LAST_BYTE) {
free_extent_map(em);
em = search_extent_mapping(em_tree, 0, 0);
- if (em && em->block_start < EXTENT_MAP_LAST_BYTE)
- alloc_hint = em->block_start;
+ if (em && em->disk_bytenr < EXTENT_MAP_LAST_BYTE)
+ alloc_hint = extent_map_block_start(em);
if (em)
free_extent_map(em);
} else {
- alloc_hint = em->block_start;
+ alloc_hint = extent_map_block_start(em);
free_extent_map(em);
}
}
@@ -1452,7 +1451,6 @@ static noinline int cow_file_range(struct btrfs_inode *inode,
&cached);
em = create_io_em(inode, start, ins.offset, /* len */
- ins.objectid, /* block_start */
ins.offset, /* orig_block_len */
ram_size, /* ram_bytes */
BTRFS_COMPRESS_NONE, /* compress_type */
@@ -2189,7 +2187,6 @@ must_cow:
struct extent_map *em;
em = create_io_em(inode, cur_offset, nocow_args.num_bytes,
- nocow_args.disk_bytenr, /* block_start */
nocow_args.disk_num_bytes, /* orig_block_len */
ram_bytes, BTRFS_COMPRESS_NONE,
&nocow_args.file_extent,
@@ -2704,7 +2701,7 @@ static int btrfs_find_new_delalloc_bytes(struct btrfs_inode *inode,
if (IS_ERR(em))
return PTR_ERR(em);
- if (em->block_start != EXTENT_MAP_HOLE)
+ if (em->disk_bytenr != EXTENT_MAP_HOLE)
goto next;
em_len = em->len;
@@ -5023,7 +5020,6 @@ int btrfs_cont_expand(struct btrfs_inode *inode, loff_t oldsize, loff_t size)
hole_em->start = cur_offset;
hole_em->len = hole_size;
- hole_em->block_start = EXTENT_MAP_HOLE;
hole_em->disk_bytenr = EXTENT_MAP_HOLE;
hole_em->disk_num_bytes = 0;
hole_em->ram_bytes = hole_size;
@@ -6880,7 +6876,7 @@ struct extent_map *btrfs_get_extent(struct btrfs_inode *inode,
if (em) {
if (em->start > start || em->start + em->len <= start)
free_extent_map(em);
- else if (em->block_start == EXTENT_MAP_INLINE && page)
+ else if (em->disk_bytenr == EXTENT_MAP_INLINE && page)
free_extent_map(em);
else
goto out;
@@ -6983,7 +6979,7 @@ next:
/* New extent overlaps with existing one */
em->start = start;
em->len = found_key.offset - start;
- em->block_start = EXTENT_MAP_HOLE;
+ em->disk_bytenr = EXTENT_MAP_HOLE;
goto insert;
}
@@ -7007,7 +7003,7 @@ next:
*
* Other members are not utilized for inline extents.
*/
- ASSERT(em->block_start == EXTENT_MAP_INLINE);
+ ASSERT(em->disk_bytenr == EXTENT_MAP_INLINE);
ASSERT(em->len == fs_info->sectorsize);
ret = read_inline_extent(inode, path, page);
@@ -7018,7 +7014,7 @@ next:
not_found:
em->start = start;
em->len = len;
- em->block_start = EXTENT_MAP_HOLE;
+ em->disk_bytenr = EXTENT_MAP_HOLE;
insert:
ret = 0;
btrfs_release_path(path);
@@ -7049,7 +7045,6 @@ static struct extent_map *btrfs_create_dio_extent(struct btrfs_inode *inode,
struct btrfs_dio_data *dio_data,
const u64 start,
const u64 len,
- const u64 block_start,
const u64 orig_block_len,
const u64 ram_bytes,
const int type,
@@ -7059,15 +7054,32 @@ static struct extent_map *btrfs_create_dio_extent(struct btrfs_inode *inode,
struct btrfs_ordered_extent *ordered;
if (type != BTRFS_ORDERED_NOCOW) {
- em = create_io_em(inode, start, len, block_start,
+ em = create_io_em(inode, start, len,
orig_block_len, ram_bytes,
BTRFS_COMPRESS_NONE, /* compress_type */
file_extent, type);
if (IS_ERR(em))
goto out;
}
+
+ /*
+ * For regular writes, file_extent->offset is always 0, thus we really
+ * only need file_extent->disk_bytenr, every other length
+ * (disk_num_bytes/ram_bytes) should match @len and file_extent->num_bytes.
+ *
+ * For NOCOW, we don't really care about the numbers except @start and
+ * @len, as we won't insert a file extent item at all.
+ *
+ * For PREALLOC, we do not use ordered extent members, but
+ * btrfs_mark_extent_written() handles everything.
+ *
+ * So here we always pass 0 as offset for the ordered extent,
+ * otherwise btrfs_split_ordered_extent() cannot handle it correctly.
+ */
ordered = btrfs_alloc_ordered_extent(inode, start, len, len,
- block_start, len, 0,
+ file_extent->disk_bytenr +
+ file_extent->offset,
+ len, 0,
(1 << type) |
(1 << BTRFS_ORDERED_DIRECT),
BTRFS_COMPRESS_NONE);
@@ -7119,7 +7131,7 @@ again:
file_extent.offset = 0;
file_extent.compression = BTRFS_COMPRESS_NONE;
em = btrfs_create_dio_extent(inode, dio_data, start, ins.offset,
- ins.objectid, ins.offset,
+ ins.offset,
ins.offset, BTRFS_ORDERED_REGULAR,
&file_extent);
btrfs_dec_block_group_reservations(fs_info, ins.objectid);
@@ -7358,7 +7370,7 @@ static int lock_extent_direct(struct inode *inode, u64 lockstart, u64 lockend,
/* The callers of this must take lock_extent() */
static struct extent_map *create_io_em(struct btrfs_inode *inode, u64 start,
- u64 len, u64 block_start,
+ u64 len,
u64 disk_num_bytes,
u64 ram_bytes, int compress_type,
const struct btrfs_file_extent *file_extent,
@@ -7410,7 +7422,6 @@ static struct extent_map *create_io_em(struct btrfs_inode *inode, u64 start,
em->start = start;
em->len = len;
- em->block_start = block_start;
em->disk_bytenr = file_extent->disk_bytenr;
em->disk_num_bytes = disk_num_bytes;
em->ram_bytes = ram_bytes;
@@ -7461,13 +7472,13 @@ static int btrfs_get_blocks_direct_write(struct extent_map **map,
*/
if ((em->flags & EXTENT_FLAG_PREALLOC) ||
((BTRFS_I(inode)->flags & BTRFS_INODE_NODATACOW) &&
- em->block_start != EXTENT_MAP_HOLE)) {
+ em->disk_bytenr != EXTENT_MAP_HOLE)) {
if (em->flags & EXTENT_FLAG_PREALLOC)
type = BTRFS_ORDERED_PREALLOC;
else
type = BTRFS_ORDERED_NOCOW;
len = min(len, em->len - (start - em->start));
- block_start = em->block_start + (start - em->start);
+ block_start = extent_map_block_start(em) + (start - em->start);
if (can_nocow_extent(inode, start, &len,
&orig_block_len, &ram_bytes,
@@ -7497,7 +7508,6 @@ static int btrfs_get_blocks_direct_write(struct extent_map **map,
space_reserved = true;
em2 = btrfs_create_dio_extent(BTRFS_I(inode), dio_data, start, len,
- block_start,
orig_block_len,
ram_bytes, type,
&file_extent);
@@ -7699,8 +7709,7 @@ static int btrfs_dio_iomap_begin(struct inode *inode, loff_t start,
* to buffered IO. Don't blame me, this is the price we pay for using
* the generic code.
*/
- if (extent_map_is_compressed(em) ||
- em->block_start == EXTENT_MAP_INLINE) {
+ if (extent_map_is_compressed(em) || em->disk_bytenr == EXTENT_MAP_INLINE) {
free_extent_map(em);
/*
* If we are in a NOWAIT context, return -EAGAIN in order to
@@ -7794,12 +7803,12 @@ static int btrfs_dio_iomap_begin(struct inode *inode, loff_t start,
* We trim the extents (and move the addr) even though iomap code does
* that, since we have locked only the parts we are performing I/O in.
*/
- if ((em->block_start == EXTENT_MAP_HOLE) ||
+ if ((em->disk_bytenr == EXTENT_MAP_HOLE) ||
((em->flags & EXTENT_FLAG_PREALLOC) && !write)) {
iomap->addr = IOMAP_NULL_ADDR;
iomap->type = IOMAP_HOLE;
} else {
- iomap->addr = em->block_start + (start - em->start);
+ iomap->addr = extent_map_block_start(em) + (start - em->start);
iomap->type = IOMAP_MAPPED;
}
iomap->offset = start;
@@ -9590,7 +9599,6 @@ static int __btrfs_prealloc_file_range(struct inode *inode, int mode,
em->start = cur_offset;
em->len = ins.offset;
- em->block_start = ins.objectid;
em->disk_bytenr = ins.objectid;
em->offset = 0;
em->disk_num_bytes = ins.offset;
@@ -10056,7 +10064,7 @@ ssize_t btrfs_encoded_read(struct kiocb *iocb, struct iov_iter *iter,
goto out_unlock_extent;
}
- if (em->block_start == EXTENT_MAP_INLINE) {
+ if (em->disk_bytenr == EXTENT_MAP_INLINE) {
u64 extent_start = em->start;
/*
@@ -10077,14 +10085,14 @@ ssize_t btrfs_encoded_read(struct kiocb *iocb, struct iov_iter *iter,
*/
encoded->len = min_t(u64, extent_map_end(em),
inode->vfs_inode.i_size) - iocb->ki_pos;
- if (em->block_start == EXTENT_MAP_HOLE ||
+ if (em->disk_bytenr == EXTENT_MAP_HOLE ||
(em->flags & EXTENT_FLAG_PREALLOC)) {
disk_bytenr = EXTENT_MAP_HOLE;
count = min_t(u64, count, encoded->len);
encoded->len = count;
encoded->unencoded_len = count;
} else if (extent_map_is_compressed(em)) {
- disk_bytenr = em->block_start;
+ disk_bytenr = em->disk_bytenr;
/*
* Bail if the buffer isn't large enough to return the whole
* compressed extent.
@@ -10103,7 +10111,7 @@ ssize_t btrfs_encoded_read(struct kiocb *iocb, struct iov_iter *iter,
goto out_em;
encoded->compression = ret;
} else {
- disk_bytenr = em->block_start + (start - em->start);
+ disk_bytenr = extent_map_block_start(em) + (start - em->start);
if (encoded->len > count)
encoded->len = count;
/*
@@ -10341,7 +10349,6 @@ ssize_t btrfs_do_encoded_write(struct kiocb *iocb, struct iov_iter *from,
file_extent.offset = encoded->unencoded_offset;
file_extent.compression = compression;
em = create_io_em(inode, start, num_bytes,
- ins.objectid,
ins.offset, ram_bytes, compression,
&file_extent, BTRFS_ORDERED_COMPRESSED);
if (IS_ERR(em)) {
@@ -10645,12 +10652,12 @@ static int btrfs_swap_activate(struct swap_info_struct *sis, struct file *file,
goto out;
}
- if (em->block_start == EXTENT_MAP_HOLE) {
+ if (em->disk_bytenr == EXTENT_MAP_HOLE) {
btrfs_warn(fs_info, "swapfile must not have holes");
ret = -EINVAL;
goto out;
}
- if (em->block_start == EXTENT_MAP_INLINE) {
+ if (em->disk_bytenr == EXTENT_MAP_INLINE) {
/*
* It's unlikely we'll ever actually find ourselves
* here, as a file small enough to fit inline won't be
@@ -10668,7 +10675,7 @@ static int btrfs_swap_activate(struct swap_info_struct *sis, struct file *file,
goto out;
}
- logical_block_start = em->block_start + (start - em->start);
+ logical_block_start = extent_map_block_start(em) + (start - em->start);
len = min(len, em->len - (start - em->start));
free_extent_map(em);
em = NULL;