while (!list_empty(&dir_list)) {
struct extent_buffer *leaf;
struct btrfs_key min_key;
+ u64 ino;
+ bool continue_curr_inode = true;
int nritems;
int i;
dir_elem = list_first_entry(&dir_list, struct btrfs_dir_list,
list);
- if (ret)
- goto next_dir_inode;
+ ino = dir_elem->ino;
+ list_del(&dir_elem->list);
+ kfree(dir_elem);
- min_key.objectid = dir_elem->ino;
+ min_key.objectid = ino;
min_key.type = BTRFS_DIR_INDEX_KEY;
min_key.offset = 0;
again:
btrfs_release_path(path);
ret = btrfs_search_forward(root, &min_key, path, trans->transid);
if (ret < 0) {
- goto next_dir_inode;
+ break;
} else if (ret > 0) {
ret = 0;
- goto next_dir_inode;
+ continue;
}
leaf = path->nodes[0];
struct btrfs_dir_item *di;
struct btrfs_key di_key;
struct inode *di_inode;
- struct btrfs_dir_list *new_dir_elem;
int log_mode = LOG_INODE_EXISTS;
int type;
btrfs_item_key_to_cpu(leaf, &min_key, i);
- if (min_key.objectid != dir_elem->ino ||
- min_key.type != BTRFS_DIR_INDEX_KEY)
- goto next_dir_inode;
+ if (min_key.objectid != ino ||
+ min_key.type != BTRFS_DIR_INDEX_KEY) {
+ continue_curr_inode = false;
+ break;
+ }
di = btrfs_item_ptr(leaf, i, struct btrfs_dir_item);
type = btrfs_dir_type(leaf, di);
di_inode = btrfs_iget(fs_info->sb, di_key.objectid, root);
if (IS_ERR(di_inode)) {
ret = PTR_ERR(di_inode);
- goto next_dir_inode;
+ goto out;
}
if (!need_log_inode(trans, BTRFS_I(di_inode))) {
log_mode, ctx);
btrfs_add_delayed_iput(di_inode);
if (ret)
- goto next_dir_inode;
+ goto out;
if (ctx->log_new_dentries) {
- new_dir_elem = kmalloc(sizeof(*new_dir_elem),
- GFP_NOFS);
- if (!new_dir_elem) {
+ dir_elem = kmalloc(sizeof(*dir_elem), GFP_NOFS);
+ if (!dir_elem) {
ret = -ENOMEM;
- goto next_dir_inode;
+ goto out;
}
- new_dir_elem->ino = di_key.objectid;
- list_add_tail(&new_dir_elem->list, &dir_list);
+ dir_elem->ino = di_key.objectid;
+ list_add_tail(&dir_elem->list, &dir_list);
}
break;
}
- if (min_key.offset < (u64)-1) {
+
+ if (continue_curr_inode && min_key.offset < (u64)-1) {
min_key.offset++;
goto again;
}
-next_dir_inode:
- list_del(&dir_elem->list);
- kfree(dir_elem);
}
-
+out:
btrfs_free_path(path);
+ if (ret) {
+ struct btrfs_dir_list *next;
+
+ list_for_each_entry_safe(dir_elem, next, &dir_list, list)
+ kfree(dir_elem);
+ }
+
return ret;
}