mirror of
https://mirrors.bfsu.edu.cn/git/linux.git
synced 2024-12-01 08:04:22 +08:00
a37f232b7b
Due to the complex nature of btrfs extent tree, when we want to iterate all backrefs of one extent, this involves quite a lot of work, like searching the EXTENT_ITEM/METADATA_ITEM, iteration through inline and keyed backrefs. Normally this would result in a 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. Reviewed-by: Johannes Thumshirn <johannes.thumshirn@wdc.com> Reviewed-by: Josef Bacik <josef@toxicpanda.com> Signed-off-by: Qu Wenruo <wqu@suse.com> Reviewed-by: David Sterba <dsterba@suse.com> Signed-off-by: David Sterba <dsterba@suse.com>
120 lines
3.4 KiB
C
120 lines
3.4 KiB
C
/* SPDX-License-Identifier: GPL-2.0 */
|
|
/*
|
|
* Copyright (C) 2011 STRATO. All rights reserved.
|
|
*/
|
|
|
|
#ifndef BTRFS_BACKREF_H
|
|
#define BTRFS_BACKREF_H
|
|
|
|
#include <linux/btrfs.h>
|
|
#include "ulist.h"
|
|
#include "extent_io.h"
|
|
|
|
struct inode_fs_paths {
|
|
struct btrfs_path *btrfs_path;
|
|
struct btrfs_root *fs_root;
|
|
struct btrfs_data_container *fspath;
|
|
};
|
|
|
|
typedef int (iterate_extent_inodes_t)(u64 inum, u64 offset, u64 root,
|
|
void *ctx);
|
|
|
|
int extent_from_logical(struct btrfs_fs_info *fs_info, u64 logical,
|
|
struct btrfs_path *path, struct btrfs_key *found_key,
|
|
u64 *flags);
|
|
|
|
int tree_backref_for_extent(unsigned long *ptr, struct extent_buffer *eb,
|
|
struct btrfs_key *key, struct btrfs_extent_item *ei,
|
|
u32 item_size, u64 *out_root, u8 *out_level);
|
|
|
|
int iterate_extent_inodes(struct btrfs_fs_info *fs_info,
|
|
u64 extent_item_objectid,
|
|
u64 extent_offset, int search_commit_root,
|
|
iterate_extent_inodes_t *iterate, void *ctx,
|
|
bool ignore_offset);
|
|
|
|
int iterate_inodes_from_logical(u64 logical, struct btrfs_fs_info *fs_info,
|
|
struct btrfs_path *path,
|
|
iterate_extent_inodes_t *iterate, void *ctx,
|
|
bool ignore_offset);
|
|
|
|
int paths_from_inode(u64 inum, struct inode_fs_paths *ipath);
|
|
|
|
int btrfs_find_all_leafs(struct btrfs_trans_handle *trans,
|
|
struct btrfs_fs_info *fs_info, u64 bytenr,
|
|
u64 time_seq, struct ulist **leafs,
|
|
const u64 *extent_item_pos, bool ignore_offset);
|
|
int btrfs_find_all_roots(struct btrfs_trans_handle *trans,
|
|
struct btrfs_fs_info *fs_info, u64 bytenr,
|
|
u64 time_seq, struct ulist **roots, bool ignore_offset);
|
|
char *btrfs_ref_to_path(struct btrfs_root *fs_root, struct btrfs_path *path,
|
|
u32 name_len, unsigned long name_off,
|
|
struct extent_buffer *eb_in, u64 parent,
|
|
char *dest, u32 size);
|
|
|
|
struct btrfs_data_container *init_data_container(u32 total_bytes);
|
|
struct inode_fs_paths *init_ipath(s32 total_bytes, struct btrfs_root *fs_root,
|
|
struct btrfs_path *path);
|
|
void free_ipath(struct inode_fs_paths *ipath);
|
|
|
|
int btrfs_find_one_extref(struct btrfs_root *root, u64 inode_objectid,
|
|
u64 start_off, struct btrfs_path *path,
|
|
struct btrfs_inode_extref **ret_extref,
|
|
u64 *found_off);
|
|
int btrfs_check_shared(struct btrfs_root *root, u64 inum, u64 bytenr,
|
|
struct ulist *roots, struct ulist *tmp_ulist);
|
|
|
|
int __init btrfs_prelim_ref_init(void);
|
|
void __cold btrfs_prelim_ref_exit(void);
|
|
|
|
struct prelim_ref {
|
|
struct rb_node rbnode;
|
|
u64 root_id;
|
|
struct btrfs_key key_for_search;
|
|
int level;
|
|
int count;
|
|
struct extent_inode_elem *inode_list;
|
|
u64 parent;
|
|
u64 wanted_disk_byte;
|
|
};
|
|
|
|
/*
|
|
* Iterate backrefs of one extent.
|
|
*
|
|
* Now it only supports iteration of tree block in commit root.
|
|
*/
|
|
struct btrfs_backref_iter {
|
|
u64 bytenr;
|
|
struct btrfs_path *path;
|
|
struct btrfs_fs_info *fs_info;
|
|
struct btrfs_key cur_key;
|
|
u32 item_ptr;
|
|
u32 cur_ptr;
|
|
u32 end_ptr;
|
|
};
|
|
|
|
struct btrfs_backref_iter *btrfs_backref_iter_alloc(
|
|
struct btrfs_fs_info *fs_info, gfp_t gfp_flag);
|
|
|
|
static inline void btrfs_backref_iter_free(struct btrfs_backref_iter *iter)
|
|
{
|
|
if (!iter)
|
|
return;
|
|
btrfs_free_path(iter->path);
|
|
kfree(iter);
|
|
}
|
|
|
|
int btrfs_backref_iter_start(struct btrfs_backref_iter *iter, u64 bytenr);
|
|
|
|
static inline void btrfs_backref_iter_release(struct btrfs_backref_iter *iter)
|
|
{
|
|
iter->bytenr = 0;
|
|
iter->item_ptr = 0;
|
|
iter->cur_ptr = 0;
|
|
iter->end_ptr = 0;
|
|
btrfs_release_path(iter->path);
|
|
memset(&iter->cur_key, 0, sizeof(iter->cur_key));
|
|
}
|
|
|
|
#endif
|