0001
0002
0003
0004
0005
0006 #ifndef BTRFS_BACKREF_H
0007 #define BTRFS_BACKREF_H
0008
0009 #include <linux/btrfs.h>
0010 #include "ulist.h"
0011 #include "disk-io.h"
0012 #include "extent_io.h"
0013
0014 struct inode_fs_paths {
0015 struct btrfs_path *btrfs_path;
0016 struct btrfs_root *fs_root;
0017 struct btrfs_data_container *fspath;
0018 };
0019
0020 typedef int (iterate_extent_inodes_t)(u64 inum, u64 offset, u64 root,
0021 void *ctx);
0022
0023 int extent_from_logical(struct btrfs_fs_info *fs_info, u64 logical,
0024 struct btrfs_path *path, struct btrfs_key *found_key,
0025 u64 *flags);
0026
0027 int tree_backref_for_extent(unsigned long *ptr, struct extent_buffer *eb,
0028 struct btrfs_key *key, struct btrfs_extent_item *ei,
0029 u32 item_size, u64 *out_root, u8 *out_level);
0030
0031 int iterate_extent_inodes(struct btrfs_fs_info *fs_info,
0032 u64 extent_item_objectid,
0033 u64 extent_offset, int search_commit_root,
0034 iterate_extent_inodes_t *iterate, void *ctx,
0035 bool ignore_offset);
0036
0037 int iterate_inodes_from_logical(u64 logical, struct btrfs_fs_info *fs_info,
0038 struct btrfs_path *path, void *ctx,
0039 bool ignore_offset);
0040
0041 int paths_from_inode(u64 inum, struct inode_fs_paths *ipath);
0042
0043 int btrfs_find_all_leafs(struct btrfs_trans_handle *trans,
0044 struct btrfs_fs_info *fs_info, u64 bytenr,
0045 u64 time_seq, struct ulist **leafs,
0046 const u64 *extent_item_pos, bool ignore_offset);
0047 int btrfs_find_all_roots(struct btrfs_trans_handle *trans,
0048 struct btrfs_fs_info *fs_info, u64 bytenr,
0049 u64 time_seq, struct ulist **roots,
0050 bool skip_commit_root_sem);
0051 char *btrfs_ref_to_path(struct btrfs_root *fs_root, struct btrfs_path *path,
0052 u32 name_len, unsigned long name_off,
0053 struct extent_buffer *eb_in, u64 parent,
0054 char *dest, u32 size);
0055
0056 struct btrfs_data_container *init_data_container(u32 total_bytes);
0057 struct inode_fs_paths *init_ipath(s32 total_bytes, struct btrfs_root *fs_root,
0058 struct btrfs_path *path);
0059 void free_ipath(struct inode_fs_paths *ipath);
0060
0061 int btrfs_find_one_extref(struct btrfs_root *root, u64 inode_objectid,
0062 u64 start_off, struct btrfs_path *path,
0063 struct btrfs_inode_extref **ret_extref,
0064 u64 *found_off);
0065 int btrfs_check_shared(struct btrfs_root *root, u64 inum, u64 bytenr,
0066 struct ulist *roots, struct ulist *tmp_ulist);
0067
0068 int __init btrfs_prelim_ref_init(void);
0069 void __cold btrfs_prelim_ref_exit(void);
0070
0071 struct prelim_ref {
0072 struct rb_node rbnode;
0073 u64 root_id;
0074 struct btrfs_key key_for_search;
0075 int level;
0076 int count;
0077 struct extent_inode_elem *inode_list;
0078 u64 parent;
0079 u64 wanted_disk_byte;
0080 };
0081
0082
0083
0084
0085
0086
0087 struct btrfs_backref_iter {
0088 u64 bytenr;
0089 struct btrfs_path *path;
0090 struct btrfs_fs_info *fs_info;
0091 struct btrfs_key cur_key;
0092 u32 item_ptr;
0093 u32 cur_ptr;
0094 u32 end_ptr;
0095 };
0096
0097 struct btrfs_backref_iter *btrfs_backref_iter_alloc(
0098 struct btrfs_fs_info *fs_info, gfp_t gfp_flag);
0099
0100 static inline void btrfs_backref_iter_free(struct btrfs_backref_iter *iter)
0101 {
0102 if (!iter)
0103 return;
0104 btrfs_free_path(iter->path);
0105 kfree(iter);
0106 }
0107
0108 static inline struct extent_buffer *btrfs_backref_get_eb(
0109 struct btrfs_backref_iter *iter)
0110 {
0111 if (!iter)
0112 return NULL;
0113 return iter->path->nodes[0];
0114 }
0115
0116
0117
0118
0119
0120
0121
0122 static inline bool btrfs_backref_has_tree_block_info(
0123 struct btrfs_backref_iter *iter)
0124 {
0125 if (iter->cur_key.type == BTRFS_EXTENT_ITEM_KEY &&
0126 iter->cur_ptr - iter->item_ptr == sizeof(struct btrfs_extent_item))
0127 return true;
0128 return false;
0129 }
0130
0131 int btrfs_backref_iter_start(struct btrfs_backref_iter *iter, u64 bytenr);
0132
0133 int btrfs_backref_iter_next(struct btrfs_backref_iter *iter);
0134
0135 static inline bool btrfs_backref_iter_is_inline_ref(
0136 struct btrfs_backref_iter *iter)
0137 {
0138 if (iter->cur_key.type == BTRFS_EXTENT_ITEM_KEY ||
0139 iter->cur_key.type == BTRFS_METADATA_ITEM_KEY)
0140 return true;
0141 return false;
0142 }
0143
0144 static inline void btrfs_backref_iter_release(struct btrfs_backref_iter *iter)
0145 {
0146 iter->bytenr = 0;
0147 iter->item_ptr = 0;
0148 iter->cur_ptr = 0;
0149 iter->end_ptr = 0;
0150 btrfs_release_path(iter->path);
0151 memset(&iter->cur_key, 0, sizeof(iter->cur_key));
0152 }
0153
0154
0155
0156
0157
0158
0159
0160
0161
0162
0163
0164 struct btrfs_backref_node {
0165 struct {
0166 struct rb_node rb_node;
0167 u64 bytenr;
0168 };
0169
0170 u64 new_bytenr;
0171
0172 u64 owner;
0173
0174 struct list_head list;
0175
0176
0177 struct list_head upper;
0178
0179 struct list_head lower;
0180
0181
0182 struct btrfs_root *root;
0183
0184 struct extent_buffer *eb;
0185
0186 unsigned int level:8;
0187
0188 unsigned int cowonly:1;
0189
0190 unsigned int lowest:1;
0191
0192 unsigned int locked:1;
0193
0194 unsigned int processed:1;
0195
0196 unsigned int checked:1;
0197
0198
0199
0200
0201 unsigned int pending:1;
0202
0203 unsigned int detached:1;
0204
0205
0206
0207
0208
0209 unsigned int is_reloc_root:1;
0210 };
0211
0212 #define LOWER 0
0213 #define UPPER 1
0214
0215
0216
0217
0218 struct btrfs_backref_edge {
0219
0220
0221
0222
0223
0224
0225
0226
0227 struct list_head list[2];
0228
0229
0230 struct btrfs_backref_node *node[2];
0231 };
0232
0233 struct btrfs_backref_cache {
0234
0235 struct rb_root rb_root;
0236
0237 struct btrfs_backref_node *path[BTRFS_MAX_LEVEL];
0238
0239
0240
0241
0242 struct list_head pending[BTRFS_MAX_LEVEL];
0243
0244 struct list_head leaves;
0245
0246 struct list_head changed;
0247
0248 struct list_head detached;
0249
0250 u64 last_trans;
0251
0252 int nr_nodes;
0253 int nr_edges;
0254
0255
0256 struct list_head pending_edge;
0257
0258
0259 struct list_head useless_node;
0260
0261 struct btrfs_fs_info *fs_info;
0262
0263
0264
0265
0266
0267
0268
0269 unsigned int is_reloc;
0270 };
0271
0272 void btrfs_backref_init_cache(struct btrfs_fs_info *fs_info,
0273 struct btrfs_backref_cache *cache, int is_reloc);
0274 struct btrfs_backref_node *btrfs_backref_alloc_node(
0275 struct btrfs_backref_cache *cache, u64 bytenr, int level);
0276 struct btrfs_backref_edge *btrfs_backref_alloc_edge(
0277 struct btrfs_backref_cache *cache);
0278
0279 #define LINK_LOWER (1 << 0)
0280 #define LINK_UPPER (1 << 1)
0281 static inline void btrfs_backref_link_edge(struct btrfs_backref_edge *edge,
0282 struct btrfs_backref_node *lower,
0283 struct btrfs_backref_node *upper,
0284 int link_which)
0285 {
0286 ASSERT(upper && lower && upper->level == lower->level + 1);
0287 edge->node[LOWER] = lower;
0288 edge->node[UPPER] = upper;
0289 if (link_which & LINK_LOWER)
0290 list_add_tail(&edge->list[LOWER], &lower->upper);
0291 if (link_which & LINK_UPPER)
0292 list_add_tail(&edge->list[UPPER], &upper->lower);
0293 }
0294
0295 static inline void btrfs_backref_free_node(struct btrfs_backref_cache *cache,
0296 struct btrfs_backref_node *node)
0297 {
0298 if (node) {
0299 ASSERT(list_empty(&node->list));
0300 ASSERT(list_empty(&node->lower));
0301 ASSERT(node->eb == NULL);
0302 cache->nr_nodes--;
0303 btrfs_put_root(node->root);
0304 kfree(node);
0305 }
0306 }
0307
0308 static inline void btrfs_backref_free_edge(struct btrfs_backref_cache *cache,
0309 struct btrfs_backref_edge *edge)
0310 {
0311 if (edge) {
0312 cache->nr_edges--;
0313 kfree(edge);
0314 }
0315 }
0316
0317 static inline void btrfs_backref_unlock_node_buffer(
0318 struct btrfs_backref_node *node)
0319 {
0320 if (node->locked) {
0321 btrfs_tree_unlock(node->eb);
0322 node->locked = 0;
0323 }
0324 }
0325
0326 static inline void btrfs_backref_drop_node_buffer(
0327 struct btrfs_backref_node *node)
0328 {
0329 if (node->eb) {
0330 btrfs_backref_unlock_node_buffer(node);
0331 free_extent_buffer(node->eb);
0332 node->eb = NULL;
0333 }
0334 }
0335
0336
0337
0338
0339
0340
0341
0342
0343 static inline void btrfs_backref_drop_node(struct btrfs_backref_cache *tree,
0344 struct btrfs_backref_node *node)
0345 {
0346 ASSERT(list_empty(&node->upper));
0347
0348 btrfs_backref_drop_node_buffer(node);
0349 list_del_init(&node->list);
0350 list_del_init(&node->lower);
0351 if (!RB_EMPTY_NODE(&node->rb_node))
0352 rb_erase(&node->rb_node, &tree->rb_root);
0353 btrfs_backref_free_node(tree, node);
0354 }
0355
0356 void btrfs_backref_cleanup_node(struct btrfs_backref_cache *cache,
0357 struct btrfs_backref_node *node);
0358
0359 void btrfs_backref_release_cache(struct btrfs_backref_cache *cache);
0360
0361 static inline void btrfs_backref_panic(struct btrfs_fs_info *fs_info,
0362 u64 bytenr, int errno)
0363 {
0364 btrfs_panic(fs_info, errno,
0365 "Inconsistency in backref cache found at offset %llu",
0366 bytenr);
0367 }
0368
0369 int btrfs_backref_add_tree_node(struct btrfs_backref_cache *cache,
0370 struct btrfs_path *path,
0371 struct btrfs_backref_iter *iter,
0372 struct btrfs_key *node_key,
0373 struct btrfs_backref_node *cur);
0374
0375 int btrfs_backref_finish_upper_links(struct btrfs_backref_cache *cache,
0376 struct btrfs_backref_node *start);
0377
0378 void btrfs_backref_error_cleanup(struct btrfs_backref_cache *cache,
0379 struct btrfs_backref_node *node);
0380
0381 #endif