backref.c (1f422417945d08731e2915e0addb976f11b3a85a) | backref.c (a37f232b7b65789cadc9834d389f6390de11b583) |
---|---|
1// SPDX-License-Identifier: GPL-2.0 2/* 3 * Copyright (C) 2011 STRATO. All rights reserved. 4 */ 5 6#include <linux/mm.h> 7#include <linux/rbtree.h> 8#include <trace/events/btrfs.h> --- 377 unchanged lines hidden (view full) --- 386 wanted_disk_byte, count, sc, gfp_mask); 387} 388 389static int is_shared_data_backref(struct preftrees *preftrees, u64 bytenr) 390{ 391 struct rb_node **p = &preftrees->direct.root.rb_root.rb_node; 392 struct rb_node *parent = NULL; 393 struct prelim_ref *ref = NULL; | 1// SPDX-License-Identifier: GPL-2.0 2/* 3 * Copyright (C) 2011 STRATO. All rights reserved. 4 */ 5 6#include <linux/mm.h> 7#include <linux/rbtree.h> 8#include <trace/events/btrfs.h> --- 377 unchanged lines hidden (view full) --- 386 wanted_disk_byte, count, sc, gfp_mask); 387} 388 389static int is_shared_data_backref(struct preftrees *preftrees, u64 bytenr) 390{ 391 struct rb_node **p = &preftrees->direct.root.rb_root.rb_node; 392 struct rb_node *parent = NULL; 393 struct prelim_ref *ref = NULL; |
394 struct prelim_ref target = {0}; | 394 struct prelim_ref target = {}; |
395 int result; 396 397 target.parent = bytenr; 398 399 while (*p) { 400 parent = *p; 401 ref = rb_entry(parent, struct prelim_ref, rbnode); 402 result = prelim_ref_compare(ref, &target); --- 1887 unchanged lines hidden (view full) --- 2290 2291void free_ipath(struct inode_fs_paths *ipath) 2292{ 2293 if (!ipath) 2294 return; 2295 kvfree(ipath->fspath); 2296 kfree(ipath); 2297} | 395 int result; 396 397 target.parent = bytenr; 398 399 while (*p) { 400 parent = *p; 401 ref = rb_entry(parent, struct prelim_ref, rbnode); 402 result = prelim_ref_compare(ref, &target); --- 1887 unchanged lines hidden (view full) --- 2290 2291void free_ipath(struct inode_fs_paths *ipath) 2292{ 2293 if (!ipath) 2294 return; 2295 kvfree(ipath->fspath); 2296 kfree(ipath); 2297} |
2298 2299struct btrfs_backref_iter *btrfs_backref_iter_alloc( 2300 struct btrfs_fs_info *fs_info, gfp_t gfp_flag) 2301{ 2302 struct btrfs_backref_iter *ret; 2303 2304 ret = kzalloc(sizeof(*ret), gfp_flag); 2305 if (!ret) 2306 return NULL; 2307 2308 ret->path = btrfs_alloc_path(); 2309 if (!ret) { 2310 kfree(ret); 2311 return NULL; 2312 } 2313 2314 /* Current backref iterator only supports iteration in commit root */ 2315 ret->path->search_commit_root = 1; 2316 ret->path->skip_locking = 1; 2317 ret->fs_info = fs_info; 2318 2319 return ret; 2320} 2321 2322int btrfs_backref_iter_start(struct btrfs_backref_iter *iter, u64 bytenr) 2323{ 2324 struct btrfs_fs_info *fs_info = iter->fs_info; 2325 struct btrfs_path *path = iter->path; 2326 struct btrfs_extent_item *ei; 2327 struct btrfs_key key; 2328 int ret; 2329 2330 key.objectid = bytenr; 2331 key.type = BTRFS_METADATA_ITEM_KEY; 2332 key.offset = (u64)-1; 2333 iter->bytenr = bytenr; 2334 2335 ret = btrfs_search_slot(NULL, fs_info->extent_root, &key, path, 0, 0); 2336 if (ret < 0) 2337 return ret; 2338 if (ret == 0) { 2339 ret = -EUCLEAN; 2340 goto release; 2341 } 2342 if (path->slots[0] == 0) { 2343 WARN_ON(IS_ENABLED(CONFIG_BTRFS_DEBUG)); 2344 ret = -EUCLEAN; 2345 goto release; 2346 } 2347 path->slots[0]--; 2348 2349 btrfs_item_key_to_cpu(path->nodes[0], &key, path->slots[0]); 2350 if ((key.type != BTRFS_EXTENT_ITEM_KEY && 2351 key.type != BTRFS_METADATA_ITEM_KEY) || key.objectid != bytenr) { 2352 ret = -ENOENT; 2353 goto release; 2354 } 2355 memcpy(&iter->cur_key, &key, sizeof(key)); 2356 iter->item_ptr = (u32)btrfs_item_ptr_offset(path->nodes[0], 2357 path->slots[0]); 2358 iter->end_ptr = (u32)(iter->item_ptr + 2359 btrfs_item_size_nr(path->nodes[0], path->slots[0])); 2360 ei = btrfs_item_ptr(path->nodes[0], path->slots[0], 2361 struct btrfs_extent_item); 2362 2363 /* 2364 * Only support iteration on tree backref yet. 2365 * 2366 * This is an extra precaution for non skinny-metadata, where 2367 * EXTENT_ITEM is also used for tree blocks, that we can only use 2368 * extent flags to determine if it's a tree block. 2369 */ 2370 if (btrfs_extent_flags(path->nodes[0], ei) & BTRFS_EXTENT_FLAG_DATA) { 2371 ret = -ENOTSUPP; 2372 goto release; 2373 } 2374 iter->cur_ptr = (u32)(iter->item_ptr + sizeof(*ei)); 2375 2376 /* If there is no inline backref, go search for keyed backref */ 2377 if (iter->cur_ptr >= iter->end_ptr) { 2378 ret = btrfs_next_item(fs_info->extent_root, path); 2379 2380 /* No inline nor keyed ref */ 2381 if (ret > 0) { 2382 ret = -ENOENT; 2383 goto release; 2384 } 2385 if (ret < 0) 2386 goto release; 2387 2388 btrfs_item_key_to_cpu(path->nodes[0], &iter->cur_key, 2389 path->slots[0]); 2390 if (iter->cur_key.objectid != bytenr || 2391 (iter->cur_key.type != BTRFS_SHARED_BLOCK_REF_KEY && 2392 iter->cur_key.type != BTRFS_TREE_BLOCK_REF_KEY)) { 2393 ret = -ENOENT; 2394 goto release; 2395 } 2396 iter->cur_ptr = (u32)btrfs_item_ptr_offset(path->nodes[0], 2397 path->slots[0]); 2398 iter->item_ptr = iter->cur_ptr; 2399 iter->end_ptr = (u32)(iter->item_ptr + btrfs_item_size_nr( 2400 path->nodes[0], path->slots[0])); 2401 } 2402 2403 return 0; 2404release: 2405 btrfs_backref_iter_release(iter); 2406 return ret; 2407} |
|