forked from Mirrors/btrfs-progs
Btrfs-progs: pull back backref.c and fix it up
This patch pulls back backref.c, adds a couple of helpers everywhere that it needs, and cleans up backref.c to fit in btrfs-progs. Thanks, Signed-off-by: Josef Bacik <jbacik@fb.com> [removed free_some_buffers after "do not reclaim extent buffer"] Signed-off-by: David Sterba <dsterba@suse.cz>master
parent
6863bcf74f
commit
d90d8d2323
2
Makefile
2
Makefile
|
@ -10,7 +10,7 @@ objects = ctree.o disk-io.o radix-tree.o extent-tree.o print-tree.o \
|
|||
root-tree.o dir-item.o file-item.o inode-item.o inode-map.o \
|
||||
extent-cache.o extent_io.o volumes.o utils.o repair.o \
|
||||
qgroup.o raid6.o free-space-cache.o list_sort.o props.o \
|
||||
ulist.o qgroup-verify.o
|
||||
ulist.o qgroup-verify.o backref.o
|
||||
cmds_objects = cmds-subvolume.o cmds-filesystem.o cmds-device.o cmds-scrub.o \
|
||||
cmds-inspect.o cmds-balance.o cmds-send.o cmds-receive.o \
|
||||
cmds-quota.o cmds-qgroup.o cmds-replace.o cmds-check.o \
|
||||
|
|
|
@ -0,0 +1,73 @@
|
|||
/*
|
||||
* Copyright (C) 2011 STRATO. All rights reserved.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public
|
||||
* License v2 as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public
|
||||
* License along with this program; if not, write to the
|
||||
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
* Boston, MA 021110-1307, USA.
|
||||
*/
|
||||
|
||||
#ifndef __BTRFS_BACKREF__
|
||||
#define __BTRFS_BACKREF__
|
||||
|
||||
#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 inode_item_info(u64 inum, u64 ioff, struct btrfs_root *fs_root,
|
||||
struct btrfs_path *path);
|
||||
|
||||
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);
|
||||
|
||||
int iterate_inodes_from_logical(u64 logical, struct btrfs_fs_info *fs_info,
|
||||
struct btrfs_path *path,
|
||||
iterate_extent_inodes_t *iterate, void *ctx);
|
||||
|
||||
int paths_from_inode(u64 inum, struct inode_fs_paths *ipath);
|
||||
|
||||
int btrfs_find_all_roots(struct btrfs_trans_handle *trans,
|
||||
struct btrfs_fs_info *fs_info, u64 bytenr,
|
||||
u64 time_seq, struct ulist **roots);
|
||||
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);
|
||||
#endif
|
84
ctree.c
84
ctree.c
|
@ -1021,6 +1021,49 @@ void reada_for_search(struct btrfs_root *root, struct btrfs_path *path,
|
|||
}
|
||||
}
|
||||
|
||||
int btrfs_find_item(struct btrfs_root *fs_root, struct btrfs_path *found_path,
|
||||
u64 iobjectid, u64 ioff, u8 key_type,
|
||||
struct btrfs_key *found_key)
|
||||
{
|
||||
int ret;
|
||||
struct btrfs_key key;
|
||||
struct extent_buffer *eb;
|
||||
struct btrfs_path *path;
|
||||
|
||||
key.type = key_type;
|
||||
key.objectid = iobjectid;
|
||||
key.offset = ioff;
|
||||
|
||||
if (found_path == NULL) {
|
||||
path = btrfs_alloc_path();
|
||||
if (!path)
|
||||
return -ENOMEM;
|
||||
} else
|
||||
path = found_path;
|
||||
|
||||
ret = btrfs_search_slot(NULL, fs_root, &key, path, 0, 0);
|
||||
if ((ret < 0) || (found_key == NULL)) {
|
||||
if (path != found_path)
|
||||
btrfs_free_path(path);
|
||||
return ret;
|
||||
}
|
||||
|
||||
eb = path->nodes[0];
|
||||
if (ret && path->slots[0] >= btrfs_header_nritems(eb)) {
|
||||
ret = btrfs_next_leaf(fs_root, path);
|
||||
if (ret)
|
||||
return ret;
|
||||
eb = path->nodes[0];
|
||||
}
|
||||
|
||||
btrfs_item_key_to_cpu(eb, found_key, path->slots[0]);
|
||||
if (found_key->type != key.type ||
|
||||
found_key->objectid != key.objectid)
|
||||
return 1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* look for key in the tree. path is filled in with nodes along the way
|
||||
* if key is found, we return zero and you can find the item in the leaf
|
||||
|
@ -2813,3 +2856,44 @@ int btrfs_previous_item(struct btrfs_root *root,
|
|||
return 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* search in extent tree to find a previous Metadata/Data extent item with
|
||||
* min objecitd.
|
||||
*
|
||||
* returns 0 if something is found, 1 if nothing was found and < 0 on error
|
||||
*/
|
||||
int btrfs_previous_extent_item(struct btrfs_root *root,
|
||||
struct btrfs_path *path, u64 min_objectid)
|
||||
{
|
||||
struct btrfs_key found_key;
|
||||
struct extent_buffer *leaf;
|
||||
u32 nritems;
|
||||
int ret;
|
||||
|
||||
while (1) {
|
||||
if (path->slots[0] == 0) {
|
||||
ret = btrfs_prev_leaf(root, path);
|
||||
if (ret != 0)
|
||||
return ret;
|
||||
} else {
|
||||
path->slots[0]--;
|
||||
}
|
||||
leaf = path->nodes[0];
|
||||
nritems = btrfs_header_nritems(leaf);
|
||||
if (nritems == 0)
|
||||
return 1;
|
||||
if (path->slots[0] == nritems)
|
||||
path->slots[0]--;
|
||||
|
||||
btrfs_item_key_to_cpu(leaf, &found_key, path->slots[0]);
|
||||
if (found_key.objectid < min_objectid)
|
||||
break;
|
||||
if (found_key.type == BTRFS_EXTENT_ITEM_KEY ||
|
||||
found_key.type == BTRFS_METADATA_ITEM_KEY)
|
||||
return 0;
|
||||
if (found_key.objectid == min_objectid &&
|
||||
found_key.type < BTRFS_EXTENT_ITEM_KEY)
|
||||
break;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
|
14
ctree.h
14
ctree.h
|
@ -2253,6 +2253,8 @@ struct extent_buffer *read_node_slot(struct btrfs_root *root,
|
|||
int btrfs_previous_item(struct btrfs_root *root,
|
||||
struct btrfs_path *path, u64 min_objectid,
|
||||
int type);
|
||||
int btrfs_previous_extent_item(struct btrfs_root *root,
|
||||
struct btrfs_path *path, u64 min_objectid);
|
||||
int btrfs_cow_block(struct btrfs_trans_handle *trans,
|
||||
struct btrfs_root *root, struct extent_buffer *buf,
|
||||
struct extent_buffer *parent, int parent_slot,
|
||||
|
@ -2281,6 +2283,9 @@ int btrfs_split_item(struct btrfs_trans_handle *trans,
|
|||
int btrfs_search_slot(struct btrfs_trans_handle *trans, struct btrfs_root
|
||||
*root, struct btrfs_key *key, struct btrfs_path *p, int
|
||||
ins_len, int cow);
|
||||
int btrfs_find_item(struct btrfs_root *fs_root, struct btrfs_path *found_path,
|
||||
u64 iobjectid, u64 ioff, u8 key_type,
|
||||
struct btrfs_key *found_key);
|
||||
void btrfs_release_path(struct btrfs_path *p);
|
||||
void add_root_to_dirty_list(struct btrfs_root *root);
|
||||
struct btrfs_path *btrfs_alloc_path(void);
|
||||
|
@ -2313,6 +2318,15 @@ static inline int btrfs_insert_empty_item(struct btrfs_trans_handle *trans,
|
|||
}
|
||||
|
||||
int btrfs_next_leaf(struct btrfs_root *root, struct btrfs_path *path);
|
||||
static inline int btrfs_next_item(struct btrfs_root *root,
|
||||
struct btrfs_path *p)
|
||||
{
|
||||
++p->slots[0];
|
||||
if (p->slots[0] >= btrfs_header_nritems(p->nodes[0]))
|
||||
return btrfs_next_leaf(root, p);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int btrfs_prev_leaf(struct btrfs_root *root, struct btrfs_path *path);
|
||||
int btrfs_leaf_free_space(struct btrfs_root *root, struct extent_buffer *leaf);
|
||||
void btrfs_fixup_low_keys(struct btrfs_root *root, struct btrfs_path *path,
|
||||
|
|
41
extent_io.c
41
extent_io.c
|
@ -539,7 +539,6 @@ static struct extent_buffer *__alloc_extent_buffer(struct extent_io_tree *tree,
|
|||
u64 bytenr, u32 blocksize)
|
||||
{
|
||||
struct extent_buffer *eb;
|
||||
int ret;
|
||||
|
||||
eb = malloc(sizeof(struct extent_buffer) + blocksize);
|
||||
if (!eb) {
|
||||
|
@ -559,16 +558,23 @@ static struct extent_buffer *__alloc_extent_buffer(struct extent_io_tree *tree,
|
|||
eb->cache_node.size = blocksize;
|
||||
INIT_LIST_HEAD(&eb->recow);
|
||||
|
||||
ret = insert_cache_extent(&tree->cache, &eb->cache_node);
|
||||
if (ret) {
|
||||
free(eb);
|
||||
return NULL;
|
||||
}
|
||||
list_add_tail(&eb->lru, &tree->lru);
|
||||
tree->cache_size += blocksize;
|
||||
return eb;
|
||||
}
|
||||
|
||||
struct extent_buffer *btrfs_clone_extent_buffer(struct extent_buffer *src)
|
||||
{
|
||||
struct extent_buffer *new;
|
||||
|
||||
new = __alloc_extent_buffer(NULL, src->start, src->len);
|
||||
if (new == NULL)
|
||||
return NULL;
|
||||
|
||||
copy_extent_buffer(new, src, 0, 0, src->len);
|
||||
new->flags |= EXTENT_BUFFER_DUMMY;
|
||||
|
||||
return new;
|
||||
}
|
||||
|
||||
void free_extent_buffer(struct extent_buffer *eb)
|
||||
{
|
||||
if (!eb)
|
||||
|
@ -581,9 +587,11 @@ void free_extent_buffer(struct extent_buffer *eb)
|
|||
BUG_ON(eb->flags & EXTENT_DIRTY);
|
||||
list_del_init(&eb->lru);
|
||||
list_del_init(&eb->recow);
|
||||
remove_cache_extent(&tree->cache, &eb->cache_node);
|
||||
BUG_ON(tree->cache_size < eb->len);
|
||||
tree->cache_size -= eb->len;
|
||||
if (!(eb->flags & EXTENT_BUFFER_DUMMY)) {
|
||||
BUG_ON(tree->cache_size < eb->len);
|
||||
remove_cache_extent(&tree->cache, &eb->cache_node);
|
||||
tree->cache_size -= eb->len;
|
||||
}
|
||||
free(eb);
|
||||
}
|
||||
}
|
||||
|
@ -632,12 +640,23 @@ struct extent_buffer *alloc_extent_buffer(struct extent_io_tree *tree,
|
|||
list_move_tail(&eb->lru, &tree->lru);
|
||||
eb->refs++;
|
||||
} else {
|
||||
int ret;
|
||||
|
||||
if (cache) {
|
||||
eb = container_of(cache, struct extent_buffer,
|
||||
cache_node);
|
||||
free_extent_buffer(eb);
|
||||
}
|
||||
eb = __alloc_extent_buffer(tree, bytenr, blocksize);
|
||||
if (!eb)
|
||||
return NULL;
|
||||
ret = insert_cache_extent(&tree->cache, &eb->cache_node);
|
||||
if (ret) {
|
||||
free(eb);
|
||||
return NULL;
|
||||
}
|
||||
list_add_tail(&eb->lru, &tree->lru);
|
||||
tree->cache_size += blocksize;
|
||||
}
|
||||
return eb;
|
||||
}
|
||||
|
|
|
@ -40,6 +40,7 @@
|
|||
#define EXTENT_BUFFER_FILLED (1 << 8)
|
||||
#define EXTENT_CSUM (1 << 9)
|
||||
#define EXTENT_BAD_TRANSID (1 << 10)
|
||||
#define EXTENT_BUFFER_DUMMY (1 << 11)
|
||||
#define EXTENT_IOBITS (EXTENT_LOCKED | EXTENT_WRITEBACK)
|
||||
|
||||
#define BLOCK_GROUP_DATA EXTENT_WRITEBACK
|
||||
|
@ -111,6 +112,7 @@ struct extent_buffer *find_first_extent_buffer(struct extent_io_tree *tree,
|
|||
u64 start);
|
||||
struct extent_buffer *alloc_extent_buffer(struct extent_io_tree *tree,
|
||||
u64 bytenr, u32 blocksize);
|
||||
struct extent_buffer *btrfs_clone_extent_buffer(struct extent_buffer *src);
|
||||
void free_extent_buffer(struct extent_buffer *eb);
|
||||
int read_extent_from_disk(struct extent_buffer *eb,
|
||||
unsigned long offset, unsigned long len);
|
||||
|
|
|
@ -108,6 +108,9 @@ typedef __u32 u32;
|
|||
typedef __u64 u64;
|
||||
typedef __u16 u16;
|
||||
typedef __u8 u8;
|
||||
typedef __s64 s64;
|
||||
typedef __s32 s32;
|
||||
|
||||
/*
|
||||
* Continuing to define __KERNEL__ breaks others parts of the code, so
|
||||
* we can just undefine it now that we have the correct headers...
|
||||
|
@ -119,6 +122,8 @@ typedef unsigned int __u32;
|
|||
typedef unsigned long long u64;
|
||||
typedef unsigned char u8;
|
||||
typedef unsigned short u16;
|
||||
typedef long long s64;
|
||||
typedef int s32
|
||||
#endif
|
||||
|
||||
|
||||
|
@ -269,6 +274,8 @@ static inline long IS_ERR(const void *ptr)
|
|||
#define kzalloc(x, y) calloc(1, x)
|
||||
#define kstrdup(x, y) strdup(x)
|
||||
#define kfree(x) free(x)
|
||||
#define vmalloc(x) malloc(x)
|
||||
#define vfree(x) free(x)
|
||||
|
||||
#ifndef BTRFS_DISABLE_BACKTRACE
|
||||
#define BUG_ON(c) assert_trace(#c, __FILE__, __func__, __LINE__, !(c))
|
||||
|
|
15
ulist.h
15
ulist.h
|
@ -58,6 +58,21 @@ void ulist_free(struct ulist *ulist);
|
|||
int ulist_add(struct ulist *ulist, u64 val, u64 aux, gfp_t gfp_mask);
|
||||
int ulist_add_merge(struct ulist *ulist, u64 val, u64 aux,
|
||||
u64 *old_aux, gfp_t gfp_mask);
|
||||
|
||||
/* just like ulist_add_merge() but take a pointer for the aux data */
|
||||
static inline int ulist_add_merge_ptr(struct ulist *ulist, u64 val, void *aux,
|
||||
void **old_aux, gfp_t gfp_mask)
|
||||
{
|
||||
#if BITS_PER_LONG == 32
|
||||
u64 old64 = (uintptr_t)*old_aux;
|
||||
int ret = ulist_add_merge(ulist, val, (uintptr_t)aux, &old64, gfp_mask);
|
||||
*old_aux = (void *)((uintptr_t)old64);
|
||||
return ret;
|
||||
#else
|
||||
return ulist_add_merge(ulist, val, (u64)aux, (u64 *)old_aux, gfp_mask);
|
||||
#endif
|
||||
}
|
||||
|
||||
struct ulist_node *ulist_next(struct ulist *ulist,
|
||||
struct ulist_iterator *uiter);
|
||||
|
||||
|
|
Loading…
Reference in New Issue