unsigned int found_dir_index:1;
unsigned int found_inode_ref:1;
u8 filetype;
+ u8 ref_type;
int errors;
- unsigned int ref_type;
u64 dir;
u64 index;
u16 namelen;
static int add_inode_backref(struct cache_tree *inode_cache,
u64 ino, u64 dir, u64 index,
const char *name, int namelen,
- u8 filetype, int itemtype, int errors)
+ u8 filetype, u8 itemtype, int errors)
{
struct inode_record *rec;
struct inode_backref *backref;
struct inode_record *rec,
struct inode_backref *backref)
{
- struct btrfs_path *path;
+ struct btrfs_path path;
struct btrfs_trans_handle *trans;
struct btrfs_dir_item *dir_item;
struct extent_buffer *leaf;
u32 data_size = sizeof(*dir_item) + backref->namelen;
int ret;
- path = btrfs_alloc_path();
- if (!path)
- return -ENOMEM;
-
trans = btrfs_start_transaction(root, 1);
- if (IS_ERR(trans)) {
- btrfs_free_path(path);
+ if (IS_ERR(trans))
return PTR_ERR(trans);
- }
fprintf(stderr, "repairing missing dir index item for inode %llu\n",
(unsigned long long)rec->ino);
+
+ btrfs_init_path(&path);
key.objectid = backref->dir;
key.type = BTRFS_DIR_INDEX_KEY;
key.offset = backref->index;
-
- ret = btrfs_insert_empty_item(trans, root, path, &key, data_size);
+ ret = btrfs_insert_empty_item(trans, root, &path, &key, data_size);
BUG_ON(ret);
- leaf = path->nodes[0];
- dir_item = btrfs_item_ptr(leaf, path->slots[0], struct btrfs_dir_item);
+ leaf = path.nodes[0];
+ dir_item = btrfs_item_ptr(leaf, path.slots[0], struct btrfs_dir_item);
disk_key.objectid = cpu_to_le64(rec->ino);
disk_key.type = BTRFS_INODE_ITEM_KEY;
name_ptr = (unsigned long)(dir_item + 1);
write_extent_buffer(leaf, backref->name, name_ptr, backref->namelen);
btrfs_mark_buffer_dirty(leaf);
- btrfs_free_path(path);
+ btrfs_release_path(&path);
btrfs_commit_transaction(trans, root);
backref->found_dir_index = 1;
{
struct btrfs_trans_handle *trans;
struct btrfs_dir_item *di;
- struct btrfs_path *path;
+ struct btrfs_path path;
int ret = 0;
- path = btrfs_alloc_path();
- if (!path)
- return -ENOMEM;
-
trans = btrfs_start_transaction(root, 1);
- if (IS_ERR(trans)) {
- btrfs_free_path(path);
+ if (IS_ERR(trans))
return PTR_ERR(trans);
- }
-
fprintf(stderr, "Deleting bad dir index [%llu,%u,%llu] root %llu\n",
(unsigned long long)backref->dir,
BTRFS_DIR_INDEX_KEY, (unsigned long long)backref->index,
(unsigned long long)root->objectid);
- di = btrfs_lookup_dir_index(trans, root, path, backref->dir,
+ btrfs_init_path(&path);
+ di = btrfs_lookup_dir_index(trans, root, &path, backref->dir,
backref->name, backref->namelen,
backref->index, -1);
if (IS_ERR(di)) {
ret = PTR_ERR(di);
- btrfs_free_path(path);
+ btrfs_release_path(&path);
btrfs_commit_transaction(trans, root);
if (ret == -ENOENT)
return 0;
}
if (!di)
- ret = btrfs_del_item(trans, root, path);
+ ret = btrfs_del_item(trans, root, &path);
else
- ret = btrfs_delete_one_dir_name(trans, root, path, di);
+ ret = btrfs_delete_one_dir_name(trans, root, &path, di);
BUG_ON(ret);
- btrfs_free_path(path);
+ btrfs_release_path(&path);
btrfs_commit_transaction(trans, root);
return ret;
}
*/
static int find_normal_file_extent(struct btrfs_root *root, u64 ino)
{
- struct btrfs_path *path;
+ struct btrfs_path path;
struct btrfs_key key;
struct btrfs_key found_key;
struct btrfs_file_extent_item *fi;
u8 type;
int ret = 0;
- path = btrfs_alloc_path();
- if (!path)
- goto out;
+ btrfs_init_path(&path);
key.objectid = ino;
key.type = BTRFS_EXTENT_DATA_KEY;
key.offset = 0;
- ret = btrfs_search_slot(NULL, root, &key, path, 0, 0);
+ ret = btrfs_search_slot(NULL, root, &key, &path, 0, 0);
if (ret < 0) {
ret = 0;
goto out;
}
- if (ret && path->slots[0] >= btrfs_header_nritems(path->nodes[0])) {
- ret = btrfs_next_leaf(root, path);
+ if (ret && path.slots[0] >= btrfs_header_nritems(path.nodes[0])) {
+ ret = btrfs_next_leaf(root, &path);
if (ret) {
ret = 0;
goto out;
}
}
while (1) {
- btrfs_item_key_to_cpu(path->nodes[0], &found_key,
- path->slots[0]);
+ btrfs_item_key_to_cpu(path.nodes[0], &found_key,
+ path.slots[0]);
if (found_key.objectid != ino ||
found_key.type != BTRFS_EXTENT_DATA_KEY)
break;
- fi = btrfs_item_ptr(path->nodes[0], path->slots[0],
+ fi = btrfs_item_ptr(path.nodes[0], path.slots[0],
struct btrfs_file_extent_item);
- type = btrfs_file_extent_type(path->nodes[0], fi);
+ type = btrfs_file_extent_type(path.nodes[0], fi);
if (type != BTRFS_FILE_EXTENT_INLINE) {
ret = 1;
goto out;
}
}
out:
- btrfs_free_path(path);
+ btrfs_release_path(&path);
return ret;
}
static int try_repair_inode(struct btrfs_root *root, struct inode_record *rec)
{
struct btrfs_trans_handle *trans;
- struct btrfs_path *path;
+ struct btrfs_path path;
int ret = 0;
if (!(rec->errors & (I_ERR_DIR_ISIZE_WRONG |
I_ERR_FILE_NBYTES_WRONG)))
return rec->errors;
- path = btrfs_alloc_path();
- if (!path)
- return -ENOMEM;
-
/*
* For nlink repair, it may create a dir and add link, so
* 2 for parent(256)'s dir_index and dir_item
* 2 for lost+found dir's dir_index and dir_item for the file
*/
trans = btrfs_start_transaction(root, 7);
- if (IS_ERR(trans)) {
- btrfs_free_path(path);
+ if (IS_ERR(trans))
return PTR_ERR(trans);
- }
+ btrfs_init_path(&path);
if (rec->errors & I_ERR_NO_INODE_ITEM)
- ret = repair_inode_no_item(trans, root, path, rec);
+ ret = repair_inode_no_item(trans, root, &path, rec);
if (!ret && rec->errors & I_ERR_FILE_EXTENT_ORPHAN)
- ret = repair_inode_orphan_extent(trans, root, path, rec);
+ ret = repair_inode_orphan_extent(trans, root, &path, rec);
if (!ret && rec->errors & I_ERR_FILE_EXTENT_DISCOUNT)
- ret = repair_inode_discount_extent(trans, root, path, rec);
+ ret = repair_inode_discount_extent(trans, root, &path, rec);
if (!ret && rec->errors & I_ERR_DIR_ISIZE_WRONG)
- ret = repair_inode_isize(trans, root, path, rec);
+ ret = repair_inode_isize(trans, root, &path, rec);
if (!ret && rec->errors & I_ERR_NO_ORPHAN_ITEM)
- ret = repair_inode_orphan_item(trans, root, path, rec);
+ ret = repair_inode_orphan_item(trans, root, &path, rec);
if (!ret && rec->errors & I_ERR_LINK_COUNT_WRONG)
- ret = repair_inode_nlinks(trans, root, path, rec);
+ ret = repair_inode_nlinks(trans, root, &path, rec);
if (!ret && rec->errors & I_ERR_FILE_NBYTES_WRONG)
- ret = repair_inode_nbytes(trans, root, path, rec);
+ ret = repair_inode_nbytes(trans, root, &path, rec);
btrfs_commit_transaction(trans, root);
- btrfs_free_path(path);
+ btrfs_release_path(&path);
return ret;
}
struct cache_tree *corrupt_blocks)
{
struct btrfs_trans_handle *trans;
- struct btrfs_path *path;
+ struct btrfs_path path;
struct btrfs_corrupt_block *corrupt;
struct cache_extent *cache;
struct btrfs_key key;
if (cache_tree_empty(corrupt_blocks))
return 0;
- path = btrfs_alloc_path();
- if (!path)
- return -ENOMEM;
-
trans = btrfs_start_transaction(root, 1);
if (IS_ERR(trans)) {
ret = PTR_ERR(trans);
fprintf(stderr, "Error starting transaction: %s\n",
strerror(-ret));
- goto out_free_path;
+ return ret;
}
+ btrfs_init_path(&path);
cache = first_cache_extent(corrupt_blocks);
while (cache) {
corrupt = container_of(cache, struct btrfs_corrupt_block,
cache);
level = corrupt->level;
- path->lowest_level = level;
+ path.lowest_level = level;
key.objectid = corrupt->key.objectid;
key.type = corrupt->key.type;
key.offset = corrupt->key.offset;
* so ins_len set to 0 here.
* Balance will be done after all corrupt node/leaf is deleted.
*/
- ret = btrfs_search_slot(trans, root, &key, path, 0, 1);
+ ret = btrfs_search_slot(trans, root, &key, &path, 0, 1);
if (ret < 0)
goto out;
- offset = btrfs_node_blockptr(path->nodes[level],
- path->slots[level]);
+ offset = btrfs_node_blockptr(path.nodes[level],
+ path.slots[level]);
/* Remove the ptr */
- ret = btrfs_del_ptr(trans, root, path, level,
- path->slots[level]);
+ ret = btrfs_del_ptr(trans, root, &path, level,
+ path.slots[level]);
if (ret < 0)
goto out;
/*
* Remove the corresponding extent
* return value is not concerned.
*/
- btrfs_release_path(path);
+ btrfs_release_path(&path);
ret = btrfs_free_extent(trans, root, offset, root->nodesize,
0, root->root_key.objectid,
level - 1, 0);
corrupt = container_of(cache, struct btrfs_corrupt_block,
cache);
memcpy(&key, &corrupt->key, sizeof(key));
- ret = btrfs_search_slot(trans, root, &key, path, -1, 1);
+ ret = btrfs_search_slot(trans, root, &key, &path, -1, 1);
if (ret < 0)
goto out;
/* return will always >0 since it won't find the item */
ret = 0;
- btrfs_release_path(path);
+ btrfs_release_path(&path);
cache = next_cache_extent(cache);
}
out:
btrfs_commit_transaction(trans, root);
-out_free_path:
- btrfs_free_path(path);
+ btrfs_release_path(&path);
return ret;
}
struct ulist *roots;
struct ulist_node *node;
struct btrfs_root *search_root;
- struct btrfs_path *path;
+ struct btrfs_path path;
struct ulist_iterator iter;
struct btrfs_key root_key, key;
int ret;
status != BTRFS_TREE_BLOCK_INVALID_OFFSETS)
return -EIO;
- path = btrfs_alloc_path();
- if (!path)
- return -EIO;
-
- ret = btrfs_find_all_roots(NULL, root->fs_info, buf->start,
- 0, &roots);
- if (ret) {
- btrfs_free_path(path);
+ ret = btrfs_find_all_roots(NULL, root->fs_info, buf->start, 0, &roots);
+ if (ret)
return -EIO;
- }
+ btrfs_init_path(&path);
ULIST_ITER_INIT(&iter);
while ((node = ulist_next(roots, &iter))) {
root_key.objectid = node->val;
break;
}
- path->lowest_level = btrfs_header_level(buf);
- path->skip_check_block = 1;
- if (path->lowest_level)
+ path.lowest_level = btrfs_header_level(buf);
+ path.skip_check_block = 1;
+ if (path.lowest_level)
btrfs_node_key_to_cpu(buf, &key, 0);
else
btrfs_item_key_to_cpu(buf, &key, 0);
- ret = btrfs_search_slot(trans, search_root, &key, path, 0, 1);
+ ret = btrfs_search_slot(trans, search_root, &key, &path, 0, 1);
if (ret) {
ret = -EIO;
btrfs_commit_transaction(trans, search_root);
break;
}
if (status == BTRFS_TREE_BLOCK_BAD_KEY_ORDER)
- ret = fix_key_order(trans, search_root, path);
+ ret = fix_key_order(trans, search_root, &path);
else if (status == BTRFS_TREE_BLOCK_INVALID_OFFSETS)
- ret = fix_item_offset(trans, search_root, path);
+ ret = fix_item_offset(trans, search_root, &path);
if (ret) {
btrfs_commit_transaction(trans, search_root);
break;
}
- btrfs_release_path(path);
+ btrfs_release_path(&path);
btrfs_commit_transaction(trans, search_root);
}
ulist_free(roots);
- btrfs_free_path(path);
+ btrfs_release_path(&path);
return ret;
}
static int verify_space_cache(struct btrfs_root *root,
struct btrfs_block_group_cache *cache)
{
- struct btrfs_path *path;
+ struct btrfs_path path;
struct extent_buffer *leaf;
struct btrfs_key key;
u64 last;
int ret = 0;
- path = btrfs_alloc_path();
- if (!path)
- return -ENOMEM;
-
root = root->fs_info->extent_root;
last = max_t(u64, cache->key.objectid, BTRFS_SUPER_INFO_OFFSET);
+ btrfs_init_path(&path);
key.objectid = last;
key.offset = 0;
key.type = BTRFS_EXTENT_ITEM_KEY;
-
- ret = btrfs_search_slot(NULL, root, &key, path, 0, 0);
+ ret = btrfs_search_slot(NULL, root, &key, &path, 0, 0);
if (ret < 0)
goto out;
ret = 0;
while (1) {
- if (path->slots[0] >= btrfs_header_nritems(path->nodes[0])) {
- ret = btrfs_next_leaf(root, path);
+ if (path.slots[0] >= btrfs_header_nritems(path.nodes[0])) {
+ ret = btrfs_next_leaf(root, &path);
if (ret < 0)
goto out;
if (ret > 0) {
break;
}
}
- leaf = path->nodes[0];
- btrfs_item_key_to_cpu(leaf, &key, path->slots[0]);
+ leaf = path.nodes[0];
+ btrfs_item_key_to_cpu(leaf, &key, path.slots[0]);
if (key.objectid >= cache->key.offset + cache->key.objectid)
break;
if (key.type != BTRFS_EXTENT_ITEM_KEY &&
key.type != BTRFS_METADATA_ITEM_KEY) {
- path->slots[0]++;
+ path.slots[0]++;
continue;
}
last = key.objectid + key.offset;
else
last = key.objectid + root->nodesize;
- path->slots[0]++;
+ path.slots[0]++;
continue;
}
last = key.objectid + key.offset;
else
last = key.objectid + root->nodesize;
- path->slots[0]++;
+ path.slots[0]++;
}
if (last < cache->key.objectid + cache->key.offset)
cache->key.offset - last);
out:
- btrfs_free_path(path);
+ btrfs_release_path(&path);
if (!ret &&
!RB_EMPTY_ROOT(&cache->free_space_ctl->free_space_offset)) {
static int check_extent_exists(struct btrfs_root *root, u64 bytenr,
u64 num_bytes)
{
- struct btrfs_path *path;
+ struct btrfs_path path;
struct extent_buffer *leaf;
struct btrfs_key key;
int ret;
- path = btrfs_alloc_path();
- if (!path) {
- fprintf(stderr, "Error allocating path\n");
- return -ENOMEM;
- }
-
+ btrfs_init_path(&path);
key.objectid = bytenr;
key.type = BTRFS_EXTENT_ITEM_KEY;
key.offset = (u64)-1;
again:
- ret = btrfs_search_slot(NULL, root->fs_info->extent_root, &key, path,
+ ret = btrfs_search_slot(NULL, root->fs_info->extent_root, &key, &path,
0, 0);
if (ret < 0) {
fprintf(stderr, "Error looking up extent record %d\n", ret);
- btrfs_free_path(path);
+ btrfs_release_path(&path);
return ret;
} else if (ret) {
- if (path->slots[0] > 0) {
- path->slots[0]--;
+ if (path.slots[0] > 0) {
+ path.slots[0]--;
} else {
- ret = btrfs_prev_leaf(root, path);
+ ret = btrfs_prev_leaf(root, &path);
if (ret < 0) {
goto out;
} else if (ret > 0) {
}
}
- btrfs_item_key_to_cpu(path->nodes[0], &key, path->slots[0]);
+ btrfs_item_key_to_cpu(path.nodes[0], &key, path.slots[0]);
/*
* Block group items come before extent items if they have the same
* EXTENT_ITEM_KEY please?
*/
while (key.type > BTRFS_EXTENT_ITEM_KEY) {
- if (path->slots[0] > 0) {
- path->slots[0]--;
+ if (path.slots[0] > 0) {
+ path.slots[0]--;
} else {
- ret = btrfs_prev_leaf(root, path);
+ ret = btrfs_prev_leaf(root, &path);
if (ret < 0) {
goto out;
} else if (ret > 0) {
goto out;
}
}
- btrfs_item_key_to_cpu(path->nodes[0], &key, path->slots[0]);
+ btrfs_item_key_to_cpu(path.nodes[0], &key, path.slots[0]);
}
while (num_bytes) {
- if (path->slots[0] >= btrfs_header_nritems(path->nodes[0])) {
- ret = btrfs_next_leaf(root, path);
+ if (path.slots[0] >= btrfs_header_nritems(path.nodes[0])) {
+ ret = btrfs_next_leaf(root, &path);
if (ret < 0) {
fprintf(stderr, "Error going to next leaf "
"%d\n", ret);
- btrfs_free_path(path);
+ btrfs_release_path(&path);
return ret;
} else if (ret) {
break;
}
}
- leaf = path->nodes[0];
- btrfs_item_key_to_cpu(leaf, &key, path->slots[0]);
+ leaf = path.nodes[0];
+ btrfs_item_key_to_cpu(leaf, &key, path.slots[0]);
if (key.type != BTRFS_EXTENT_ITEM_KEY) {
- path->slots[0]++;
+ path.slots[0]++;
continue;
}
if (key.objectid + key.offset < bytenr) {
- path->slots[0]++;
+ path.slots[0]++;
continue;
}
if (key.objectid > bytenr + num_bytes)
* in real life, but no harm in coding it up
* anyway just in case.
*/
- btrfs_release_path(path);
+ btrfs_release_path(&path);
ret = check_extent_exists(root, new_start,
new_bytes);
if (ret) {
}
num_bytes = key.objectid - bytenr;
}
- path->slots[0]++;
+ path.slots[0]++;
}
ret = 0;
ret = 1;
}
- btrfs_free_path(path);
+ btrfs_release_path(&path);
return ret;
}
static int check_csums(struct btrfs_root *root)
{
- struct btrfs_path *path;
+ struct btrfs_path path;
struct extent_buffer *leaf;
struct btrfs_key key;
u64 offset = 0, num_bytes = 0;
return -ENOENT;
}
+ btrfs_init_path(&path);
key.objectid = BTRFS_EXTENT_CSUM_OBJECTID;
key.type = BTRFS_EXTENT_CSUM_KEY;
key.offset = 0;
-
- path = btrfs_alloc_path();
- if (!path)
- return -ENOMEM;
-
- ret = btrfs_search_slot(NULL, root, &key, path, 0, 0);
+ ret = btrfs_search_slot(NULL, root, &key, &path, 0, 0);
if (ret < 0) {
fprintf(stderr, "Error searching csum tree %d\n", ret);
- btrfs_free_path(path);
+ btrfs_release_path(&path);
return ret;
}
- if (ret > 0 && path->slots[0])
- path->slots[0]--;
+ if (ret > 0 && path.slots[0])
+ path.slots[0]--;
ret = 0;
while (1) {
- if (path->slots[0] >= btrfs_header_nritems(path->nodes[0])) {
- ret = btrfs_next_leaf(root, path);
+ if (path.slots[0] >= btrfs_header_nritems(path.nodes[0])) {
+ ret = btrfs_next_leaf(root, &path);
if (ret < 0) {
fprintf(stderr, "Error going to next leaf "
"%d\n", ret);
if (ret)
break;
}
- leaf = path->nodes[0];
+ leaf = path.nodes[0];
- btrfs_item_key_to_cpu(leaf, &key, path->slots[0]);
+ btrfs_item_key_to_cpu(leaf, &key, path.slots[0]);
if (key.type != BTRFS_EXTENT_CSUM_KEY) {
- path->slots[0]++;
+ path.slots[0]++;
continue;
}
- data_len = (btrfs_item_size_nr(leaf, path->slots[0]) /
+ data_len = (btrfs_item_size_nr(leaf, path.slots[0]) /
csum_size) * root->sectorsize;
if (!check_data_csum)
goto skip_csum_check;
- leaf_offset = btrfs_item_ptr_offset(leaf, path->slots[0]);
+ leaf_offset = btrfs_item_ptr_offset(leaf, path.slots[0]);
ret = check_extent_csums(root, key.offset, data_len,
leaf_offset, leaf);
if (ret)
num_bytes = 0;
}
num_bytes += data_len;
- path->slots[0]++;
+ path.slots[0]++;
}
- btrfs_free_path(path);
+ btrfs_release_path(&path);
return errors;
}
struct extent_buffer *leaf;
struct btrfs_key ins_key;
struct btrfs_extent_item *ei;
- struct tree_backref *tback;
struct data_backref *dback;
struct btrfs_tree_block_info *bi;
} else {
struct btrfs_disk_key copy_key;;
- tback = to_tree_backref(back);
bi = (struct btrfs_tree_block_info *)(ei + 1);
memset_extent_buffer(leaf, 0, (unsigned long)bi,
sizeof(*bi));
dback->found_ref);
} else {
u64 parent;
+ struct tree_backref *tback;
tback = to_tree_backref(back);
if (back->full_backref)
struct extent_entry *entry, *best = NULL, *prev = NULL;
list_for_each_entry(entry, entries, list) {
- if (!prev) {
- prev = entry;
- continue;
- }
-
/*
* If there are as many broken entries as entries then we know
* not to trust this particular entry.
continue;
/*
+ * Special case, when there are only two entries and 'best' is
+ * the first one
+ */
+ if (!prev) {
+ best = entry;
+ prev = entry;
+ continue;
+ }
+
+ /*
* If our current entry == best then we can't be sure our best
* is really the best, so we need to keep searching.
*/
{
struct btrfs_trans_handle *trans;
LIST_HEAD(delete_list);
- struct btrfs_path *path;
+ struct btrfs_path path;
struct extent_record *tmp, *good, *n;
int nr_del = 0;
int ret = 0, err;
struct btrfs_key key;
- path = btrfs_alloc_path();
- if (!path) {
- ret = -ENOMEM;
- goto out;
- }
+ btrfs_init_path(&path);
good = rec;
/* Find the record that covers all of the duplicates. */
abort();
}
- ret = btrfs_search_slot(trans, root, &key, path, -1, 1);
+ ret = btrfs_search_slot(trans, root, &key, &path, -1, 1);
if (ret) {
if (ret > 0)
ret = -EINVAL;
break;
}
- ret = btrfs_del_item(trans, root, path);
+ ret = btrfs_del_item(trans, root, &path);
if (ret)
break;
- btrfs_release_path(path);
+ btrfs_release_path(&path);
nr_del++;
}
err = btrfs_commit_transaction(trans, root);
free(tmp);
}
- btrfs_free_path(path);
+ btrfs_release_path(&path);
if (!ret && !nr_del)
rec->num_duplicates = 0;
struct extent_backref *back;
struct data_backref *dback;
struct orphan_data_extent *orphan;
- struct btrfs_path *path;
+ struct btrfs_path path;
int recorded_data_ref = 0;
int ret = 0;
if (rec->metadata)
return 1;
- path = btrfs_alloc_path();
- if (!path)
- return -ENOMEM;
+ btrfs_init_path(&path);
list_for_each_entry(back, &rec->backrefs, list) {
if (back->full_backref || !back->is_data ||
!back->found_extent_tree)
key.type = BTRFS_EXTENT_DATA_KEY;
key.offset = dback->offset;
- ret = btrfs_search_slot(NULL, dest_root, &key, path, 0, 0);
- btrfs_release_path(path);
+ ret = btrfs_search_slot(NULL, dest_root, &key, &path, 0, 0);
+ btrfs_release_path(&path);
/*
* For ret < 0, it's OK since the fs-tree may be corrupted,
* we need to record it for inode/file extent rebuild.
recorded_data_ref = 1;
}
out:
- btrfs_free_path(path);
+ btrfs_release_path(&path);
if (!ret)
return !recorded_data_ref;
else
{
struct btrfs_trans_handle *trans = NULL;
int ret;
- struct btrfs_path *path;
+ struct btrfs_path path;
struct list_head *cur = rec->backrefs.next;
struct cache_extent *cache;
struct extent_backref *back;
if (rec->flag_block_full_backref)
flags |= BTRFS_BLOCK_FLAG_FULL_BACKREF;
- path = btrfs_alloc_path();
- if (!path)
- return -ENOMEM;
-
+ btrfs_init_path(&path);
if (rec->refs != rec->extent_item_refs && !rec->metadata) {
/*
* Sometimes the backrefs themselves are so broken they don't
* them into the list if we find the backref so that
* verify_backrefs can figure out what to do.
*/
- ret = find_possible_backrefs(info, path, extent_cache, rec);
+ ret = find_possible_backrefs(info, &path, extent_cache, rec);
if (ret < 0)
goto out;
}
/* step one, make sure all of the backrefs agree */
- ret = verify_backrefs(info, path, rec);
+ ret = verify_backrefs(info, &path, rec);
if (ret < 0)
goto out;
}
/* step two, delete all the existing records */
- ret = delete_extent_records(trans, info->extent_root, path,
+ ret = delete_extent_records(trans, info->extent_root, &path,
rec->start, rec->max_size);
if (ret < 0)
continue;
rec->bad_full_backref = 0;
- ret = record_extent(trans, info, path, rec, back, allocated, flags);
+ ret = record_extent(trans, info, &path, rec, back, allocated, flags);
allocated = 1;
if (ret)
ret = err;
}
- btrfs_free_path(path);
+ btrfs_release_path(&path);
return ret;
}
{
struct btrfs_trans_handle *trans;
struct btrfs_root *root = fs_info->extent_root;
- struct btrfs_path *path;
+ struct btrfs_path path;
struct btrfs_extent_item *ei;
struct btrfs_key key;
u64 flags;
key.offset = rec->max_size;
}
- path = btrfs_alloc_path();
- if (!path)
- return -ENOMEM;
-
trans = btrfs_start_transaction(root, 0);
- if (IS_ERR(trans)) {
- btrfs_free_path(path);
+ if (IS_ERR(trans))
return PTR_ERR(trans);
- }
- ret = btrfs_search_slot(trans, root, &key, path, 0, 1);
+ btrfs_init_path(&path);
+ ret = btrfs_search_slot(trans, root, &key, &path, 0, 1);
if (ret < 0) {
- btrfs_free_path(path);
+ btrfs_release_path(&path);
btrfs_commit_transaction(trans, root);
return ret;
} else if (ret) {
fprintf(stderr, "Didn't find extent for %llu\n",
(unsigned long long)rec->start);
- btrfs_free_path(path);
+ btrfs_release_path(&path);
btrfs_commit_transaction(trans, root);
return -ENOENT;
}
- ei = btrfs_item_ptr(path->nodes[0], path->slots[0],
+ ei = btrfs_item_ptr(path.nodes[0], path.slots[0],
struct btrfs_extent_item);
- flags = btrfs_extent_flags(path->nodes[0], ei);
+ flags = btrfs_extent_flags(path.nodes[0], ei);
if (rec->flag_block_full_backref) {
fprintf(stderr, "setting full backref on %llu\n",
(unsigned long long)key.objectid);
(unsigned long long)key.objectid);
flags &= ~BTRFS_BLOCK_FLAG_FULL_BACKREF;
}
- btrfs_set_extent_flags(path->nodes[0], ei, flags);
- btrfs_mark_buffer_dirty(path->nodes[0]);
- btrfs_free_path(path);
+ btrfs_set_extent_flags(path.nodes[0], ei, flags);
+ btrfs_mark_buffer_dirty(path.nodes[0]);
+ btrfs_release_path(&path);
return btrfs_commit_transaction(trans, root);
}
static int reset_block_groups(struct btrfs_fs_info *fs_info)
{
struct btrfs_block_group_cache *cache;
- struct btrfs_path *path;
+ struct btrfs_path path;
struct extent_buffer *leaf;
struct btrfs_chunk *chunk;
struct btrfs_key key;
int ret;
u64 start;
- path = btrfs_alloc_path();
- if (!path)
- return -ENOMEM;
-
+ btrfs_init_path(&path);
key.objectid = 0;
key.type = BTRFS_CHUNK_ITEM_KEY;
key.offset = 0;
-
- ret = btrfs_search_slot(NULL, fs_info->chunk_root, &key, path, 0, 0);
+ ret = btrfs_search_slot(NULL, fs_info->chunk_root, &key, &path, 0, 0);
if (ret < 0) {
- btrfs_free_path(path);
+ btrfs_release_path(&path);
return ret;
}
/* First we need to create the in-memory block groups */
while (1) {
- if (path->slots[0] >= btrfs_header_nritems(path->nodes[0])) {
- ret = btrfs_next_leaf(fs_info->chunk_root, path);
+ if (path.slots[0] >= btrfs_header_nritems(path.nodes[0])) {
+ ret = btrfs_next_leaf(fs_info->chunk_root, &path);
if (ret < 0) {
- btrfs_free_path(path);
+ btrfs_release_path(&path);
return ret;
}
if (ret) {
break;
}
}
- leaf = path->nodes[0];
- btrfs_item_key_to_cpu(leaf, &key, path->slots[0]);
+ leaf = path.nodes[0];
+ btrfs_item_key_to_cpu(leaf, &key, path.slots[0]);
if (key.type != BTRFS_CHUNK_ITEM_KEY) {
- path->slots[0]++;
+ path.slots[0]++;
continue;
}
- chunk = btrfs_item_ptr(leaf, path->slots[0],
- struct btrfs_chunk);
+ chunk = btrfs_item_ptr(leaf, path.slots[0], struct btrfs_chunk);
btrfs_add_block_group(fs_info, 0,
btrfs_chunk_type(leaf, chunk),
key.objectid, key.offset,
set_extent_dirty(&fs_info->free_space_cache, key.offset,
key.offset + btrfs_chunk_length(leaf, chunk),
GFP_NOFS);
- path->slots[0]++;
+ path.slots[0]++;
}
start = 0;
while (1) {
start = cache->key.objectid + cache->key.offset;
}
- btrfs_free_path(path);
+ btrfs_release_path(&path);
return 0;
}
struct btrfs_fs_info *fs_info)
{
struct btrfs_root *root = fs_info->tree_root;
- struct btrfs_path *path;
+ struct btrfs_path path;
struct extent_buffer *leaf;
struct btrfs_key key;
int del_slot, del_nr = 0;
int ret;
int found = 0;
- path = btrfs_alloc_path();
- if (!path)
- return -ENOMEM;
-
+ btrfs_init_path(&path);
key.objectid = BTRFS_BALANCE_OBJECTID;
key.type = BTRFS_BALANCE_ITEM_KEY;
key.offset = 0;
-
- ret = btrfs_search_slot(trans, root, &key, path, -1, 1);
+ ret = btrfs_search_slot(trans, root, &key, &path, -1, 1);
if (ret) {
if (ret > 0)
ret = 0;
goto out;
}
- ret = btrfs_del_item(trans, root, path);
+ ret = btrfs_del_item(trans, root, &path);
if (ret)
goto out;
- btrfs_release_path(path);
+ btrfs_release_path(&path);
key.objectid = BTRFS_TREE_RELOC_OBJECTID;
key.type = BTRFS_ROOT_ITEM_KEY;
key.offset = 0;
-
- ret = btrfs_search_slot(trans, root, &key, path, -1, 1);
+ ret = btrfs_search_slot(trans, root, &key, &path, -1, 1);
if (ret < 0)
goto out;
while (1) {
- if (path->slots[0] >= btrfs_header_nritems(path->nodes[0])) {
+ if (path.slots[0] >= btrfs_header_nritems(path.nodes[0])) {
if (!found)
break;
if (del_nr) {
- ret = btrfs_del_items(trans, root, path,
+ ret = btrfs_del_items(trans, root, &path,
del_slot, del_nr);
del_nr = 0;
if (ret)
goto out;
}
key.offset++;
- btrfs_release_path(path);
+ btrfs_release_path(&path);
found = 0;
- ret = btrfs_search_slot(trans, root, &key, path,
+ ret = btrfs_search_slot(trans, root, &key, &path,
-1, 1);
if (ret < 0)
goto out;
continue;
}
found = 1;
- leaf = path->nodes[0];
- btrfs_item_key_to_cpu(leaf, &key, path->slots[0]);
+ leaf = path.nodes[0];
+ btrfs_item_key_to_cpu(leaf, &key, path.slots[0]);
if (key.objectid > BTRFS_TREE_RELOC_OBJECTID)
break;
if (key.objectid != BTRFS_TREE_RELOC_OBJECTID) {
- path->slots[0]++;
+ path.slots[0]++;
continue;
}
if (!del_nr) {
- del_slot = path->slots[0];
+ del_slot = path.slots[0];
del_nr = 1;
} else {
del_nr++;
}
- path->slots[0]++;
+ path.slots[0]++;
}
if (del_nr) {
- ret = btrfs_del_items(trans, root, path, del_slot, del_nr);
+ ret = btrfs_del_items(trans, root, &path, del_slot, del_nr);
if (ret)
goto out;
}
- btrfs_release_path(path);
+ btrfs_release_path(&path);
reinit_data_reloc:
key.objectid = BTRFS_DATA_RELOC_TREE_OBJECTID;
goto out;
ret = btrfs_make_root_dir(trans, root, BTRFS_FIRST_FREE_OBJECTID);
out:
- btrfs_free_path(path);
+ btrfs_release_path(&path);
return ret;
}
static int recow_extent_buffer(struct btrfs_root *root, struct extent_buffer *eb)
{
- struct btrfs_path *path;
+ struct btrfs_path path;
struct btrfs_trans_handle *trans;
struct btrfs_key key;
int ret;
return PTR_ERR(root);
}
- path = btrfs_alloc_path();
- if (!path)
- return -ENOMEM;
-
trans = btrfs_start_transaction(root, 1);
- if (IS_ERR(trans)) {
- btrfs_free_path(path);
+ if (IS_ERR(trans))
return PTR_ERR(trans);
- }
- path->lowest_level = btrfs_header_level(eb);
- if (path->lowest_level)
+ btrfs_init_path(&path);
+ path.lowest_level = btrfs_header_level(eb);
+ if (path.lowest_level)
btrfs_node_key_to_cpu(eb, &key, 0);
else
btrfs_item_key_to_cpu(eb, &key, 0);
- ret = btrfs_search_slot(trans, root, &key, path, 0, 1);
+ ret = btrfs_search_slot(trans, root, &key, &path, 0, 1);
btrfs_commit_transaction(trans, root);
- btrfs_free_path(path);
+ btrfs_release_path(&path);
return ret;
}
static int delete_bad_item(struct btrfs_root *root, struct bad_item *bad)
{
- struct btrfs_path *path;
+ struct btrfs_path path;
struct btrfs_trans_handle *trans;
struct btrfs_key key;
int ret;
return PTR_ERR(root);
}
- path = btrfs_alloc_path();
- if (!path)
- return -ENOMEM;
-
trans = btrfs_start_transaction(root, 1);
- if (IS_ERR(trans)) {
- btrfs_free_path(path);
+ if (IS_ERR(trans))
return PTR_ERR(trans);
- }
- ret = btrfs_search_slot(trans, root, &bad->key, path, -1, 1);
+ btrfs_init_path(&path);
+ ret = btrfs_search_slot(trans, root, &bad->key, &path, -1, 1);
if (ret) {
if (ret > 0)
ret = 0;
goto out;
}
- ret = btrfs_del_item(trans, root, path);
+ ret = btrfs_del_item(trans, root, &path);
out:
btrfs_commit_transaction(trans, root);
- btrfs_free_path(path);
+ btrfs_release_path(&path);
return ret;
}
struct btrfs_root *csum_root,
struct btrfs_root *cur_root)
{
- struct btrfs_path *path;
+ struct btrfs_path path;
struct btrfs_key key;
struct extent_buffer *node;
struct btrfs_file_extent_item *fi;
int slot = 0;
int ret = 0;
- path = btrfs_alloc_path();
- if (!path)
- return -ENOMEM;
buf = malloc(cur_root->fs_info->csum_root->sectorsize);
- if (!buf) {
- ret = -ENOMEM;
- goto out;
- }
+ if (!buf)
+ return -ENOMEM;
+ btrfs_init_path(&path);
key.objectid = 0;
key.offset = 0;
key.type = 0;
-
- ret = btrfs_search_slot(NULL, cur_root, &key, path, 0, 0);
+ ret = btrfs_search_slot(NULL, cur_root, &key, &path, 0, 0);
if (ret < 0)
goto out;
/* Iterate all regular file extents and fill its csum */
while (1) {
- btrfs_item_key_to_cpu(path->nodes[0], &key, path->slots[0]);
+ btrfs_item_key_to_cpu(path.nodes[0], &key, path.slots[0]);
if (key.type != BTRFS_EXTENT_DATA_KEY)
goto next;
- node = path->nodes[0];
- slot = path->slots[0];
+ node = path.nodes[0];
+ slot = path.slots[0];
fi = btrfs_item_ptr(node, slot, struct btrfs_file_extent_item);
if (btrfs_file_extent_type(node, fi) != BTRFS_FILE_EXTENT_REG)
goto next;
* TODO: if next leaf is corrupted, jump to nearest next valid
* leaf.
*/
- ret = btrfs_next_item(cur_root, path);
+ ret = btrfs_next_item(cur_root, &path);
if (ret < 0)
goto out;
if (ret > 0) {
}
out:
- btrfs_free_path(path);
+ btrfs_release_path(&path);
free(buf);
return ret;
}
struct btrfs_root *csum_root)
{
struct btrfs_fs_info *fs_info = csum_root->fs_info;
- struct btrfs_path *path;
+ struct btrfs_path path;
struct btrfs_root *tree_root = fs_info->tree_root;
struct btrfs_root *cur_root;
struct extent_buffer *node;
int slot = 0;
int ret = 0;
- path = btrfs_alloc_path();
- if (!path)
- return -ENOMEM;
-
+ btrfs_init_path(&path);
key.objectid = BTRFS_FS_TREE_OBJECTID;
key.offset = 0;
key.type = BTRFS_ROOT_ITEM_KEY;
-
- ret = btrfs_search_slot(NULL, tree_root, &key, path, 0, 0);
+ ret = btrfs_search_slot(NULL, tree_root, &key, &path, 0, 0);
if (ret < 0)
goto out;
if (ret > 0) {
}
while (1) {
- node = path->nodes[0];
- slot = path->slots[0];
+ node = path.nodes[0];
+ slot = path.slots[0];
btrfs_item_key_to_cpu(node, &key, slot);
if (key.objectid > BTRFS_LAST_FREE_OBJECTID)
goto out;
if (ret < 0)
goto out;
next:
- ret = btrfs_next_item(tree_root, path);
+ ret = btrfs_next_item(tree_root, &path);
if (ret > 0) {
ret = 0;
goto out;
}
out:
- btrfs_free_path(path);
+ btrfs_release_path(&path);
return ret;
}
struct btrfs_root *csum_root)
{
struct btrfs_root *extent_root = csum_root->fs_info->extent_root;
- struct btrfs_path *path;
+ struct btrfs_path path;
struct btrfs_extent_item *ei;
struct extent_buffer *leaf;
char *buf;
struct btrfs_key key;
int ret;
- path = btrfs_alloc_path();
- if (!path)
- return -ENOMEM;
-
+ btrfs_init_path(&path);
key.objectid = 0;
key.type = BTRFS_EXTENT_ITEM_KEY;
key.offset = 0;
-
- ret = btrfs_search_slot(NULL, extent_root, &key, path, 0, 0);
+ ret = btrfs_search_slot(NULL, extent_root, &key, &path, 0, 0);
if (ret < 0) {
- btrfs_free_path(path);
+ btrfs_release_path(&path);
return ret;
}
buf = malloc(csum_root->sectorsize);
if (!buf) {
- btrfs_free_path(path);
+ btrfs_release_path(&path);
return -ENOMEM;
}
while (1) {
- if (path->slots[0] >= btrfs_header_nritems(path->nodes[0])) {
- ret = btrfs_next_leaf(extent_root, path);
+ if (path.slots[0] >= btrfs_header_nritems(path.nodes[0])) {
+ ret = btrfs_next_leaf(extent_root, &path);
if (ret < 0)
break;
if (ret) {
break;
}
}
- leaf = path->nodes[0];
+ leaf = path.nodes[0];
- btrfs_item_key_to_cpu(leaf, &key, path->slots[0]);
+ btrfs_item_key_to_cpu(leaf, &key, path.slots[0]);
if (key.type != BTRFS_EXTENT_ITEM_KEY) {
- path->slots[0]++;
+ path.slots[0]++;
continue;
}
- ei = btrfs_item_ptr(leaf, path->slots[0],
+ ei = btrfs_item_ptr(leaf, path.slots[0],
struct btrfs_extent_item);
if (!(btrfs_extent_flags(leaf, ei) &
BTRFS_EXTENT_FLAG_DATA)) {
- path->slots[0]++;
+ path.slots[0]++;
continue;
}
key.offset);
if (ret)
break;
- path->slots[0]++;
+ path.slots[0]++;
}
- btrfs_free_path(path);
+ btrfs_release_path(&path);
free(buf);
return ret;
}
int ret = 0;
struct btrfs_key key;
struct extent_buffer *leaf;
- struct btrfs_path *path;
+ struct btrfs_path path;
if (!roots_info_cache) {
roots_info_cache = malloc(sizeof(*roots_info_cache));
cache_tree_init(roots_info_cache);
}
- path = btrfs_alloc_path();
- if (!path)
- return -ENOMEM;
-
+ btrfs_init_path(&path);
key.objectid = 0;
key.type = BTRFS_EXTENT_ITEM_KEY;
key.offset = 0;
-
- ret = btrfs_search_slot(NULL, info->extent_root, &key, path, 0, 0);
+ ret = btrfs_search_slot(NULL, info->extent_root, &key, &path, 0, 0);
if (ret < 0)
goto out;
- leaf = path->nodes[0];
+ leaf = path.nodes[0];
while (1) {
struct btrfs_key found_key;
struct btrfs_extent_item *ei;
struct btrfs_extent_inline_ref *iref;
- int slot = path->slots[0];
+ int slot = path.slots[0];
int type;
u64 flags;
u64 root_id;
struct root_item_info *rii;
if (slot >= btrfs_header_nritems(leaf)) {
- ret = btrfs_next_leaf(info->extent_root, path);
+ ret = btrfs_next_leaf(info->extent_root, &path);
if (ret < 0) {
break;
} else if (ret) {
ret = 0;
break;
}
- leaf = path->nodes[0];
- slot = path->slots[0];
+ leaf = path.nodes[0];
+ slot = path.slots[0];
}
- btrfs_item_key_to_cpu(leaf, &found_key, path->slots[0]);
+ btrfs_item_key_to_cpu(leaf, &found_key, path.slots[0]);
if (found_key.type != BTRFS_EXTENT_ITEM_KEY &&
found_key.type != BTRFS_METADATA_ITEM_KEY)
rii->node_count++;
}
next:
- path->slots[0]++;
+ path.slots[0]++;
}
out:
- btrfs_free_path(path);
+ btrfs_release_path(&path);
return ret;
}
*/
static int repair_root_items(struct btrfs_fs_info *info)
{
- struct btrfs_path *path = NULL;
+ struct btrfs_path path;
struct btrfs_key key;
struct extent_buffer *leaf;
struct btrfs_trans_handle *trans = NULL;
int bad_roots = 0;
int need_trans = 0;
+ btrfs_init_path(&path);
+
ret = build_roots_info_cache(info);
if (ret)
goto out;
- path = btrfs_alloc_path();
- if (!path) {
- ret = -ENOMEM;
- goto out;
- }
-
key.objectid = BTRFS_FIRST_FREE_OBJECTID;
key.type = BTRFS_ROOT_ITEM_KEY;
key.offset = 0;
}
}
- ret = btrfs_search_slot(trans, info->tree_root, &key, path,
+ ret = btrfs_search_slot(trans, info->tree_root, &key, &path,
0, trans ? 1 : 0);
if (ret < 0)
goto out;
- leaf = path->nodes[0];
+ leaf = path.nodes[0];
while (1) {
struct btrfs_key found_key;
- if (path->slots[0] >= btrfs_header_nritems(leaf)) {
- int no_more_keys = find_next_key(path, &key);
+ if (path.slots[0] >= btrfs_header_nritems(leaf)) {
+ int no_more_keys = find_next_key(&path, &key);
- btrfs_release_path(path);
+ btrfs_release_path(&path);
if (trans) {
ret = btrfs_commit_transaction(trans,
info->tree_root);
goto again;
}
- btrfs_item_key_to_cpu(leaf, &found_key, path->slots[0]);
+ btrfs_item_key_to_cpu(leaf, &found_key, path.slots[0]);
if (found_key.type != BTRFS_ROOT_ITEM_KEY)
goto next;
if (found_key.objectid == BTRFS_TREE_RELOC_OBJECTID)
goto next;
- ret = maybe_repair_root_item(info, path, &found_key,
+ ret = maybe_repair_root_item(info, &path, &found_key,
trans ? 0 : 1);
if (ret < 0)
goto out;
if (!trans && repair) {
need_trans = 1;
key = found_key;
- btrfs_release_path(path);
+ btrfs_release_path(&path);
goto again;
}
bad_roots++;
}
next:
- path->slots[0]++;
+ path.slots[0]++;
}
ret = 0;
out:
free_roots_info_cache();
- btrfs_free_path(path);
+ btrfs_release_path(&path);
if (trans)
btrfs_commit_transaction(trans, info->tree_root);
if (ret < 0)