On 3/17/20 4:10 AM, Qu Wenruo wrote:
Due to the complex nature of btrfs extent tree, when we want to iterate
all backrefs of one extent, it involves quite a lot of work, like
searching the EXTENT_ITEM/METADATA_ITEM, iteration through inline and keyed
backrefs.
Normally this would result pretty complex code, something like:
btrfs_search_slot()
/* Ensure we are at EXTENT_ITEM/METADATA_ITEM */
while (1) { /* Loop for extent tree items */
while (ptr < end) { /* Loop for inlined items */
/* REAL WORK HERE */
}
next:
ret = btrfs_next_item()
/* Ensure we're still at keyed item for specified bytenr */
}
The idea of btrfs_backref_iter is to avoid such complex and hard to
read code structure, but something like the following:
iter = btrfs_backref_iter_alloc();
ret = btrfs_backref_iter_start(iter, bytenr);
if (ret < 0)
goto out;
for (; ; ret = btrfs_backref_iter_next(iter)) {
/* REAL WORK HERE */
}
out:
btrfs_backref_iter_free(iter);
This patch is just the skeleton + btrfs_backref_iter_start() code.
Signed-off-by: Qu Wenruo <wqu@xxxxxxxx>
Reviewed-by: Johannes Thumshirn <johannes.thumshirn@xxxxxxx>
---
fs/btrfs/backref.c | 111 +++++++++++++++++++++++++++++++++++++++++++++
fs/btrfs/backref.h | 39 ++++++++++++++++
2 files changed, 150 insertions(+)
diff --git a/fs/btrfs/backref.c b/fs/btrfs/backref.c
index 327e4480957b..33fec39bf5ef 100644
--- a/fs/btrfs/backref.c
+++ b/fs/btrfs/backref.c
@@ -2299,3 +2299,114 @@ void free_ipath(struct inode_fs_paths *ipath)
kvfree(ipath->fspath);
kfree(ipath);
}
+
+struct btrfs_backref_iter *btrfs_backref_iter_alloc(
+ struct btrfs_fs_info *fs_info, gfp_t gfp_flag)
+{
+ struct btrfs_backref_iter *ret;
+
+ ret = kzalloc(sizeof(*ret), gfp_flag);
+ if (!ret)
+ return NULL;
+
+ ret->path = btrfs_alloc_path();
+ if (!ret) {
+ kfree(ret);
+ return NULL;
+ }
+
+ /* Current backref iterator only supports iteration in commit root */
+ ret->path->search_commit_root = 1;
+ ret->path->skip_locking = 1;
+ ret->path->reada = READA_FORWARD;
Lets kill this by default, the backref stuff is going to be random reads almost
always.
<snip>
+
+ /*
+ * Only support iteration on tree backref yet.
+ *
+ * This is extra precaustion for non skinny-metadata, where
precaution
Thanks,
Josef