Commit a5eeb3d1 authored by Filipe Manana's avatar Filipe Manana Committed by David Sterba

btrfs: add helper to get the end offset of a file extent item

Getting the end offset for a file extent item requires a bit of code since
the extent can be either inline or regular/prealloc. There are some places
all over the code base that open code this logic and in another patch
later in this series it will be needed again. Therefore encapsulate this
logic in a helper function and use it.
Reviewed-by: default avatarJosef Bacik <josef@toxicpanda.com>
Signed-off-by: default avatarFilipe Manana <fdmanana@suse.com>
Reviewed-by: default avatarDavid Sterba <dsterba@suse.com>
Signed-off-by: default avatarDavid Sterba <dsterba@suse.com>
parent 95418ed1
...@@ -2836,6 +2836,7 @@ int btrfs_inode_clear_file_extent_range(struct btrfs_inode *inode, u64 start, ...@@ -2836,6 +2836,7 @@ int btrfs_inode_clear_file_extent_range(struct btrfs_inode *inode, u64 start,
int btrfs_inode_set_file_extent_range(struct btrfs_inode *inode, u64 start, int btrfs_inode_set_file_extent_range(struct btrfs_inode *inode, u64 start,
u64 len); u64 len);
void btrfs_inode_safe_disk_i_size_write(struct inode *inode, u64 new_i_size); void btrfs_inode_safe_disk_i_size_write(struct inode *inode, u64 new_i_size);
u64 btrfs_file_extent_end(const struct btrfs_path *path);
/* inode.c */ /* inode.c */
struct extent_map *btrfs_get_extent_fiemap(struct btrfs_inode *inode, struct extent_map *btrfs_get_extent_fiemap(struct btrfs_inode *inode,
......
...@@ -1040,18 +1040,7 @@ void btrfs_extent_item_to_extent_map(struct btrfs_inode *inode, ...@@ -1040,18 +1040,7 @@ void btrfs_extent_item_to_extent_map(struct btrfs_inode *inode,
btrfs_item_key_to_cpu(leaf, &key, slot); btrfs_item_key_to_cpu(leaf, &key, slot);
extent_start = key.offset; extent_start = key.offset;
extent_end = btrfs_file_extent_end(path);
if (type == BTRFS_FILE_EXTENT_REG ||
type == BTRFS_FILE_EXTENT_PREALLOC) {
extent_end = extent_start +
btrfs_file_extent_num_bytes(leaf, fi);
} else if (type == BTRFS_FILE_EXTENT_INLINE) {
size_t size;
size = btrfs_file_extent_ram_bytes(leaf, fi);
extent_end = ALIGN(extent_start + size,
fs_info->sectorsize);
}
em->ram_bytes = btrfs_file_extent_ram_bytes(leaf, fi); em->ram_bytes = btrfs_file_extent_ram_bytes(leaf, fi);
if (type == BTRFS_FILE_EXTENT_REG || if (type == BTRFS_FILE_EXTENT_REG ||
type == BTRFS_FILE_EXTENT_PREALLOC) { type == BTRFS_FILE_EXTENT_PREALLOC) {
...@@ -1098,3 +1087,30 @@ void btrfs_extent_item_to_extent_map(struct btrfs_inode *inode, ...@@ -1098,3 +1087,30 @@ void btrfs_extent_item_to_extent_map(struct btrfs_inode *inode,
root->root_key.objectid); root->root_key.objectid);
} }
} }
/*
* Returns the end offset (non inclusive) of the file extent item the given path
* points to. If it points to an inline extent, the returned offset is rounded
* up to the sector size.
*/
u64 btrfs_file_extent_end(const struct btrfs_path *path)
{
const struct extent_buffer *leaf = path->nodes[0];
const int slot = path->slots[0];
struct btrfs_file_extent_item *fi;
struct btrfs_key key;
u64 end;
btrfs_item_key_to_cpu(leaf, &key, slot);
ASSERT(key.type == BTRFS_EXTENT_DATA_KEY);
fi = btrfs_item_ptr(leaf, slot, struct btrfs_file_extent_item);
if (btrfs_file_extent_type(leaf, fi) == BTRFS_FILE_EXTENT_INLINE) {
end = btrfs_file_extent_ram_bytes(leaf, fi);
end = ALIGN(key.offset + end, leaf->fs_info->sectorsize);
} else {
end = key.offset + btrfs_file_extent_num_bytes(leaf, fi);
}
return end;
}
...@@ -6521,6 +6521,7 @@ struct extent_map *btrfs_get_extent(struct btrfs_inode *inode, ...@@ -6521,6 +6521,7 @@ struct extent_map *btrfs_get_extent(struct btrfs_inode *inode,
extent_type = btrfs_file_extent_type(leaf, item); extent_type = btrfs_file_extent_type(leaf, item);
extent_start = found_key.offset; extent_start = found_key.offset;
extent_end = btrfs_file_extent_end(path);
if (extent_type == BTRFS_FILE_EXTENT_REG || if (extent_type == BTRFS_FILE_EXTENT_REG ||
extent_type == BTRFS_FILE_EXTENT_PREALLOC) { extent_type == BTRFS_FILE_EXTENT_PREALLOC) {
/* Only regular file could have regular/prealloc extent */ /* Only regular file could have regular/prealloc extent */
...@@ -6531,18 +6532,9 @@ struct extent_map *btrfs_get_extent(struct btrfs_inode *inode, ...@@ -6531,18 +6532,9 @@ struct extent_map *btrfs_get_extent(struct btrfs_inode *inode,
btrfs_ino(inode)); btrfs_ino(inode));
goto out; goto out;
} }
extent_end = extent_start +
btrfs_file_extent_num_bytes(leaf, item);
trace_btrfs_get_extent_show_fi_regular(inode, leaf, item, trace_btrfs_get_extent_show_fi_regular(inode, leaf, item,
extent_start); extent_start);
} else if (extent_type == BTRFS_FILE_EXTENT_INLINE) { } else if (extent_type == BTRFS_FILE_EXTENT_INLINE) {
size_t size;
size = btrfs_file_extent_ram_bytes(leaf, item);
extent_end = ALIGN(extent_start + size,
fs_info->sectorsize);
trace_btrfs_get_extent_show_fi_inline(inode, leaf, item, trace_btrfs_get_extent_show_fi_inline(inode, leaf, item,
path->slots[0], path->slots[0],
extent_start); extent_start);
......
...@@ -5586,10 +5586,7 @@ static int get_last_extent(struct send_ctx *sctx, u64 offset) ...@@ -5586,10 +5586,7 @@ static int get_last_extent(struct send_ctx *sctx, u64 offset)
{ {
struct btrfs_path *path; struct btrfs_path *path;
struct btrfs_root *root = sctx->send_root; struct btrfs_root *root = sctx->send_root;
struct btrfs_file_extent_item *fi;
struct btrfs_key key; struct btrfs_key key;
u64 extent_end;
u8 type;
int ret; int ret;
path = alloc_path_for_send(); path = alloc_path_for_send();
...@@ -5609,18 +5606,7 @@ static int get_last_extent(struct send_ctx *sctx, u64 offset) ...@@ -5609,18 +5606,7 @@ static int get_last_extent(struct send_ctx *sctx, u64 offset)
if (key.objectid != sctx->cur_ino || key.type != BTRFS_EXTENT_DATA_KEY) if (key.objectid != sctx->cur_ino || key.type != BTRFS_EXTENT_DATA_KEY)
goto out; goto out;
fi = btrfs_item_ptr(path->nodes[0], path->slots[0], sctx->cur_inode_last_extent = btrfs_file_extent_end(path);
struct btrfs_file_extent_item);
type = btrfs_file_extent_type(path->nodes[0], fi);
if (type == BTRFS_FILE_EXTENT_INLINE) {
u64 size = btrfs_file_extent_ram_bytes(path->nodes[0], fi);
extent_end = ALIGN(key.offset + size,
sctx->send_root->fs_info->sectorsize);
} else {
extent_end = key.offset +
btrfs_file_extent_num_bytes(path->nodes[0], fi);
}
sctx->cur_inode_last_extent = extent_end;
out: out:
btrfs_free_path(path); btrfs_free_path(path);
return ret; return ret;
...@@ -5674,16 +5660,7 @@ static int range_is_hole_in_parent(struct send_ctx *sctx, ...@@ -5674,16 +5660,7 @@ static int range_is_hole_in_parent(struct send_ctx *sctx,
break; break;
fi = btrfs_item_ptr(leaf, slot, struct btrfs_file_extent_item); fi = btrfs_item_ptr(leaf, slot, struct btrfs_file_extent_item);
if (btrfs_file_extent_type(leaf, fi) == extent_end = btrfs_file_extent_end(path);
BTRFS_FILE_EXTENT_INLINE) {
u64 size = btrfs_file_extent_ram_bytes(leaf, fi);
extent_end = ALIGN(key.offset + size,
root->fs_info->sectorsize);
} else {
extent_end = key.offset +
btrfs_file_extent_num_bytes(leaf, fi);
}
if (extent_end <= start) if (extent_end <= start)
goto next; goto next;
if (btrfs_file_extent_disk_bytenr(leaf, fi) == 0) { if (btrfs_file_extent_disk_bytenr(leaf, fi) == 0) {
...@@ -5704,9 +5681,6 @@ static int range_is_hole_in_parent(struct send_ctx *sctx, ...@@ -5704,9 +5681,6 @@ static int range_is_hole_in_parent(struct send_ctx *sctx,
static int maybe_send_hole(struct send_ctx *sctx, struct btrfs_path *path, static int maybe_send_hole(struct send_ctx *sctx, struct btrfs_path *path,
struct btrfs_key *key) struct btrfs_key *key)
{ {
struct btrfs_file_extent_item *fi;
u64 extent_end;
u8 type;
int ret = 0; int ret = 0;
if (sctx->cur_ino != key->objectid || !need_send_hole(sctx)) if (sctx->cur_ino != key->objectid || !need_send_hole(sctx))
...@@ -5718,18 +5692,6 @@ static int maybe_send_hole(struct send_ctx *sctx, struct btrfs_path *path, ...@@ -5718,18 +5692,6 @@ static int maybe_send_hole(struct send_ctx *sctx, struct btrfs_path *path,
return ret; return ret;
} }
fi = btrfs_item_ptr(path->nodes[0], path->slots[0],
struct btrfs_file_extent_item);
type = btrfs_file_extent_type(path->nodes[0], fi);
if (type == BTRFS_FILE_EXTENT_INLINE) {
u64 size = btrfs_file_extent_ram_bytes(path->nodes[0], fi);
extent_end = ALIGN(key->offset + size,
sctx->send_root->fs_info->sectorsize);
} else {
extent_end = key->offset +
btrfs_file_extent_num_bytes(path->nodes[0], fi);
}
if (path->slots[0] == 0 && if (path->slots[0] == 0 &&
sctx->cur_inode_last_extent < key->offset) { sctx->cur_inode_last_extent < key->offset) {
/* /*
...@@ -5755,7 +5717,7 @@ static int maybe_send_hole(struct send_ctx *sctx, struct btrfs_path *path, ...@@ -5755,7 +5717,7 @@ static int maybe_send_hole(struct send_ctx *sctx, struct btrfs_path *path,
else else
ret = 0; ret = 0;
} }
sctx->cur_inode_last_extent = extent_end; sctx->cur_inode_last_extent = btrfs_file_extent_end(path);
return ret; return ret;
} }
......
...@@ -4555,9 +4555,7 @@ static int btrfs_log_holes(struct btrfs_trans_handle *trans, ...@@ -4555,9 +4555,7 @@ static int btrfs_log_holes(struct btrfs_trans_handle *trans,
return ret; return ret;
while (true) { while (true) {
struct btrfs_file_extent_item *extent;
struct extent_buffer *leaf = path->nodes[0]; struct extent_buffer *leaf = path->nodes[0];
u64 len;
if (path->slots[0] >= btrfs_header_nritems(path->nodes[0])) { if (path->slots[0] >= btrfs_header_nritems(path->nodes[0])) {
ret = btrfs_next_leaf(root, path); ret = btrfs_next_leaf(root, path);
...@@ -4606,18 +4604,7 @@ static int btrfs_log_holes(struct btrfs_trans_handle *trans, ...@@ -4606,18 +4604,7 @@ static int btrfs_log_holes(struct btrfs_trans_handle *trans,
leaf = path->nodes[0]; leaf = path->nodes[0];
} }
extent = btrfs_item_ptr(leaf, path->slots[0], prev_extent_end = btrfs_file_extent_end(path);
struct btrfs_file_extent_item);
if (btrfs_file_extent_type(leaf, extent) ==
BTRFS_FILE_EXTENT_INLINE) {
len = btrfs_file_extent_ram_bytes(leaf, extent);
prev_extent_end = ALIGN(key.offset + len,
fs_info->sectorsize);
} else {
len = btrfs_file_extent_num_bytes(leaf, extent);
prev_extent_end = key.offset + len;
}
path->slots[0]++; path->slots[0]++;
cond_resched(); cond_resched();
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment