/* Look for the key in the destination tree. */
ret = btrfs_search_slot(NULL, root, key, path, 0, 0);
- if (ret < 0)
+ if (ret < 0) {
+ btrfs_abort_transaction(trans, ret);
return ret;
+ }
dst_eb = path->nodes[0];
dst_slot = path->slots[0];
src_copy = kmalloc(item_size, GFP_NOFS);
if (!src_copy) {
btrfs_release_path(path);
+ btrfs_abort_transaction(trans, -ENOMEM);
return -ENOMEM;
}
else if (found_size < item_size)
btrfs_extend_item(trans, path, item_size - found_size);
} else if (ret) {
+ btrfs_abort_transaction(trans, ret);
return ret;
}
dst_ptr = btrfs_item_ptr_offset(dst_eb, dst_slot);
extent_end = ALIGN(start + size,
fs_info->sectorsize);
} else {
+ btrfs_abort_transaction(trans, -EUCLEAN);
btrfs_err(fs_info,
"unexpected extent type=%d root=%llu inode=%llu offset=%llu",
found_type, btrfs_root_id(root), key->objectid, key->offset);
}
inode = btrfs_iget_logging(key->objectid, root);
- if (IS_ERR(inode))
- return PTR_ERR(inode);
+ if (IS_ERR(inode)) {
+ ret = PTR_ERR(inode);
+ btrfs_abort_transaction(trans, ret);
+ return ret;
+ }
/*
* first check to see if we already have this extent in the
drop_args.end = extent_end;
drop_args.drop_cache = true;
ret = btrfs_drop_extents(trans, root, inode, &drop_args);
- if (ret)
+ if (ret) {
+ btrfs_abort_transaction(trans, ret);
goto out;
+ }
if (found_type == BTRFS_FILE_EXTENT_REG ||
found_type == BTRFS_FILE_EXTENT_PREALLOC) {
ret = btrfs_insert_empty_item(trans, root, path, key,
sizeof(*item));
- if (ret)
+ if (ret) {
+ btrfs_abort_transaction(trans, ret);
goto out;
+ }
dest_offset = btrfs_item_ptr_offset(path->nodes[0],
path->slots[0]);
copy_extent_buffer(path->nodes[0], eb, dest_offset,
ret = btrfs_qgroup_trace_extent(trans,
btrfs_file_extent_disk_bytenr(eb, item),
btrfs_file_extent_disk_num_bytes(eb, item));
- if (ret < 0)
+ if (ret < 0) {
+ btrfs_abort_transaction(trans, ret);
goto out;
+ }
if (ins.objectid > 0) {
u64 csum_start;
ret = btrfs_lookup_data_extent(fs_info, ins.objectid,
ins.offset);
if (ret < 0) {
+ btrfs_abort_transaction(trans, ret);
goto out;
} else if (ret == 0) {
struct btrfs_ref ref = {
btrfs_init_data_ref(&ref, key->objectid, offset,
0, false);
ret = btrfs_inc_extent_ref(trans, &ref);
- if (ret)
+ if (ret) {
+ btrfs_abort_transaction(trans, ret);
goto out;
+ }
} else {
/*
* insert the extent pointer in the extent
ret = btrfs_alloc_logged_file_extent(trans,
btrfs_root_id(root),
key->objectid, offset, &ins);
- if (ret)
+ if (ret) {
+ btrfs_abort_transaction(trans, ret);
goto out;
+ }
}
btrfs_release_path(path);
ret = btrfs_lookup_csums_list(root->log_root,
csum_start, csum_end - 1,
&ordered_sums, false);
- if (ret < 0)
+ if (ret < 0) {
+ btrfs_abort_transaction(trans, ret);
goto out;
+ }
ret = 0;
/*
* Now delete all existing cums in the csum root that
list);
csum_root = btrfs_csum_root(fs_info,
sums->logical);
- if (!ret)
+ if (!ret) {
ret = btrfs_del_csums(trans, csum_root,
sums->logical,
sums->len);
- if (!ret)
+ if (ret)
+ btrfs_abort_transaction(trans, ret);
+ }
+ if (!ret) {
ret = btrfs_csum_file_blocks(trans,
csum_root,
sums);
+ if (ret)
+ btrfs_abort_transaction(trans, ret);
+ }
list_del(&sums->list);
kfree(sums);
}
}
ret = btrfs_inode_set_file_extent_range(inode, start, extent_end - start);
- if (ret)
+ if (ret) {
+ btrfs_abort_transaction(trans, ret);
goto out;
+ }
update_inode:
btrfs_update_inode_bytes(inode, nbytes, drop_args.bytes_found);
ret = btrfs_update_inode(trans, inode);
+ if (ret)
+ btrfs_abort_transaction(trans, ret);
out:
iput(&inode->vfs_inode);
return ret;
int ret;
ret = btrfs_unlink_inode(trans, dir, inode, name);
- if (ret)
+ if (ret) {
+ btrfs_abort_transaction(trans, ret);
return ret;
+ }
/*
* Whenever we need to check if a name exists or not, we check the
* fs/subvolume tree. So after an unlink we must run delayed items, so
* that future checks for a name during log replay see that the name
* does not exists anymore.
*/
- return btrfs_run_delayed_items(trans);
+ ret = btrfs_run_delayed_items(trans);
+ if (ret)
+ btrfs_abort_transaction(trans, ret);
+ return ret;
}
/*
btrfs_dir_item_key_to_cpu(leaf, di, &location);
ret = read_alloc_one_name(leaf, di + 1, btrfs_dir_name_len(leaf, di), &name);
- if (ret)
+ if (ret) {
+ btrfs_abort_transaction(trans, ret);
return ret;
+ }
btrfs_release_path(path);
inode = btrfs_iget_logging(location.objectid, root);
if (IS_ERR(inode)) {
ret = PTR_ERR(inode);
+ btrfs_abort_transaction(trans, ret);
inode = NULL;
goto out;
}
ret = read_alloc_one_name(leaf, (victim_ref + 1),
btrfs_inode_ref_name_len(leaf, victim_ref),
&victim_name);
- if (ret)
+ if (ret) {
+ btrfs_abort_transaction(trans, ret);
return ret;
+ }
ret = backref_in_log(log_root, search_key, parent_objectid, &victim_name);
if (ret) {
kfree(victim_name.name);
- if (ret < 0)
+ if (ret < 0) {
+ btrfs_abort_transaction(trans, ret);
return ret;
+ }
ptr = (unsigned long)(victim_ref + 1) + victim_name.len;
continue;
}
ret = read_alloc_one_name(leaf, &extref->name, victim_name.len,
&victim_name);
- if (ret)
+ if (ret) {
+ btrfs_abort_transaction(trans, ret);
return ret;
+ }
search_key->objectid = inode_objectid;
search_key->type = BTRFS_INODE_EXTREF_KEY;
ret = backref_in_log(log_root, search_key, parent_objectid, &victim_name);
if (ret) {
kfree(victim_name.name);
- if (ret < 0)
+ if (ret < 0) {
+ btrfs_abort_transaction(trans, ret);
return ret;
+ }
next:
cur_offset += victim_name.len + sizeof(*extref);
continue;
victim_parent = btrfs_iget_logging(parent_objectid, root);
if (IS_ERR(victim_parent)) {
kfree(victim_name.name);
- return PTR_ERR(victim_parent);
+ ret = PTR_ERR(victim_parent);
+ btrfs_abort_transaction(trans, ret);
+ return ret;
}
inc_nlink(&inode->vfs_inode);
search_key.offset = parent_objectid;
ret = btrfs_search_slot(NULL, root, &search_key, path, 0, 0);
if (ret < 0) {
+ btrfs_abort_transaction(trans, ret);
return ret;
} else if (ret == 0) {
/*
di = btrfs_lookup_dir_index_item(trans, root, path, btrfs_ino(dir),
ref_index, name, 0);
if (IS_ERR(di)) {
- return PTR_ERR(di);
+ ret = PTR_ERR(di);
+ btrfs_abort_transaction(trans, ret);
+ return ret;
} else if (di) {
ret = drop_one_dir_item(trans, path, dir, di);
if (ret)
ret = 0;
goto out;
}
- if (ret < 0)
+ if (ret < 0) {
+ btrfs_abort_transaction(trans, ret);
goto out;
+ }
eb = path->nodes[0];
ref_ptr = btrfs_item_ptr_offset(eb, path->slots[0]);
if (key->type == BTRFS_INODE_EXTREF_KEY) {
ret = extref_get_fields(eb, ref_ptr, &name,
NULL, &parent_id);
+ if (ret) {
+ btrfs_abort_transaction(trans, ret);
+ goto out;
+ }
} else {
parent_id = key->offset;
ret = ref_get_fields(eb, ref_ptr, &name, NULL);
+ if (ret) {
+ btrfs_abort_transaction(trans, ret);
+ goto out;
+ }
}
- if (ret)
- goto out;
if (key->type == BTRFS_INODE_EXTREF_KEY)
ret = !!btrfs_find_name_in_ext_backref(log_eb, log_slot,
if (IS_ERR(dir)) {
ret = PTR_ERR(dir);
kfree(name.name);
+ btrfs_abort_transaction(trans, ret);
goto out;
}
ret = unlink_inode_for_log_replay(trans, dir, inode, &name);
ret = PTR_ERR(dir);
if (ret == -ENOENT)
ret = 0;
+ else
+ btrfs_abort_transaction(trans, ret);
dir = NULL;
goto out;
}
inode = btrfs_iget_logging(inode_objectid, root);
if (IS_ERR(inode)) {
ret = PTR_ERR(inode);
+ btrfs_abort_transaction(trans, ret);
inode = NULL;
goto out;
}
if (is_extref_item) {
ret = extref_get_fields(eb, ref_ptr, &name,
&ref_index, &parent_objectid);
- if (ret)
+ if (ret) {
+ btrfs_abort_transaction(trans, ret);
goto out;
+ }
/*
* parent object can change from one array
* item to another.
*/
ret = 0;
goto next;
+ } else {
+ btrfs_abort_transaction(trans, ret);
}
goto out;
}
}
} else {
ret = ref_get_fields(eb, ref_ptr, &name, &ref_index);
- if (ret)
+ if (ret) {
+ btrfs_abort_transaction(trans, ret);
goto out;
+ }
}
ret = inode_in_dir(root, path, btrfs_ino(dir), btrfs_ino(inode),
ref_index, &name);
if (ret < 0) {
+ btrfs_abort_transaction(trans, ret);
goto out;
} else if (ret == 0) {
/*
/* insert our name */
ret = btrfs_add_link(trans, dir, inode, &name, 0, ref_index);
- if (ret)
+ if (ret) {
+ btrfs_abort_transaction(trans, ret);
goto out;
+ }
ret = btrfs_update_inode(trans, inode);
- if (ret)
+ if (ret) {
+ btrfs_abort_transaction(trans, ret);
goto out;
+ }
}
/* Else, ret == 1, we already have a perfect match, we're done. */
struct inode *vfs_inode;
inode = btrfs_iget_logging(objectid, root);
- if (IS_ERR(inode))
- return PTR_ERR(inode);
+ if (IS_ERR(inode)) {
+ ret = PTR_ERR(inode);
+ btrfs_abort_transaction(trans, ret);
+ return ret;
+ }
vfs_inode = &inode->vfs_inode;
key.objectid = BTRFS_TREE_LOG_FIXUP_OBJECTID;
ret = btrfs_update_inode(trans, inode);
} else if (ret == -EEXIST) {
ret = 0;
+ } else {
+ btrfs_abort_transaction(trans, ret);
}
iput(vfs_inode);
bool name_added = false;
dir = btrfs_iget_logging(key->objectid, root);
- if (IS_ERR(dir))
- return PTR_ERR(dir);
+ if (IS_ERR(dir)) {
+ ret = PTR_ERR(dir);
+ btrfs_abort_transaction(trans, ret);
+ return ret;
+ }
ret = read_alloc_one_name(eb, di + 1, btrfs_dir_name_len(eb, di), &name);
- if (ret)
+ if (ret) {
+ btrfs_abort_transaction(trans, ret);
goto out;
+ }
log_flags = btrfs_dir_flags(eb, di);
btrfs_dir_item_key_to_cpu(eb, di, &log_key);
ret = btrfs_lookup_inode(trans, root, path, &log_key, 0);
btrfs_release_path(path);
- if (ret < 0)
+ if (ret < 0) {
+ btrfs_abort_transaction(trans, ret);
goto out;
+ }
exists = (ret == 0);
ret = 0;
&name, 1);
if (IS_ERR(dir_dst_di)) {
ret = PTR_ERR(dir_dst_di);
+ btrfs_abort_transaction(trans, ret);
goto out;
} else if (dir_dst_di) {
ret = delete_conflicting_dir_entry(trans, dir, path, dir_dst_di,
&log_key, log_flags, exists);
- if (ret < 0)
+ if (ret < 0) {
+ btrfs_abort_transaction(trans, ret);
goto out;
+ }
dir_dst_matches = (ret == 1);
}
&name, 1);
if (IS_ERR(index_dst_di)) {
ret = PTR_ERR(index_dst_di);
+ btrfs_abort_transaction(trans, ret);
goto out;
} else if (index_dst_di) {
ret = delete_conflicting_dir_entry(trans, dir, path, index_dst_di,
&log_key, log_flags, exists);
- if (ret < 0)
+ if (ret < 0) {
+ btrfs_abort_transaction(trans, ret);
goto out;
+ }
index_dst_matches = (ret == 1);
}
search_key.offset = key->objectid;
ret = backref_in_log(root->log_root, &search_key, 0, &name);
if (ret < 0) {
+ btrfs_abort_transaction(trans, ret);
goto out;
} else if (ret) {
/* The dentry will be added later. */
search_key.offset = btrfs_extref_hash(key->objectid, name.name, name.len);
ret = backref_in_log(root->log_root, &search_key, key->objectid, &name);
if (ret < 0) {
+ btrfs_abort_transaction(trans, ret);
goto out;
} else if (ret) {
/* The dentry will be added later. */
btrfs_release_path(path);
ret = insert_one_name(trans, root, key->objectid, key->offset,
&name, &log_key);
- if (ret && ret != -ENOENT && ret != -EEXIST)
+ if (ret && ret != -ENOENT && ret != -EEXIST) {
+ btrfs_abort_transaction(trans, ret);
goto out;
+ }
if (!ret)
name_added = true;
update_size = false;
if (!ret && update_size) {
btrfs_i_size_write(dir, dir->vfs_inode.i_size + name.len * 2);
ret = btrfs_update_inode(trans, dir);
+ if (ret)
+ btrfs_abort_transaction(trans, ret);
}
kfree(name.name);
iput(&dir->vfs_inode);
struct btrfs_key di_key;
fixup_path = btrfs_alloc_path();
- if (!fixup_path)
+ if (!fixup_path) {
+ btrfs_abort_transaction(trans, -ENOMEM);
return -ENOMEM;
+ }
btrfs_dir_item_key_to_cpu(eb, di, &di_key);
ret = link_to_fixup_dir(trans, root, fixup_path, di_key.objectid);
slot = path->slots[0];
di = btrfs_item_ptr(eb, slot, struct btrfs_dir_item);
ret = read_alloc_one_name(eb, di + 1, btrfs_dir_name_len(eb, di), &name);
- if (ret)
+ if (ret) {
+ btrfs_abort_transaction(trans, ret);
goto out;
+ }
if (log) {
struct btrfs_dir_item *log_di;
dir_key->offset, &name, 0);
if (IS_ERR(log_di)) {
ret = PTR_ERR(log_di);
+ btrfs_abort_transaction(trans, ret);
goto out;
} else if (log_di) {
/* The dentry exists in the log, we have nothing to do. */
if (IS_ERR(inode)) {
ret = PTR_ERR(inode);
inode = NULL;
+ btrfs_abort_transaction(trans, ret);
goto out;
}
int ret;
log_path = btrfs_alloc_path();
- if (!log_path)
+ if (!log_path) {
+ btrfs_abort_transaction(trans, -ENOMEM);
return -ENOMEM;
+ }
search_key.objectid = ino;
search_key.type = BTRFS_XATTR_ITEM_KEY;
search_key.offset = 0;
again:
ret = btrfs_search_slot(NULL, root, &search_key, path, 0, 0);
- if (ret < 0)
+ if (ret < 0) {
+ btrfs_abort_transaction(trans, ret);
goto out;
+ }
process_leaf:
nritems = btrfs_header_nritems(path->nodes[0]);
for (i = path->slots[0]; i < nritems; i++) {
name = kmalloc(name_len, GFP_NOFS);
if (!name) {
ret = -ENOMEM;
+ btrfs_abort_transaction(trans, ret);
goto out;
}
read_extent_buffer(path->nodes[0], name,
kfree(name);
if (IS_ERR(di)) {
ret = PTR_ERR(di);
+ btrfs_abort_transaction(trans, ret);
goto out;
}
ASSERT(di);
ret = btrfs_delete_one_dir_name(trans, root,
path, di);
- if (ret)
+ if (ret) {
+ btrfs_abort_transaction(trans, ret);
goto out;
+ }
btrfs_release_path(path);
search_key = key;
goto again;
kfree(name);
if (IS_ERR(log_di)) {
ret = PTR_ERR(log_di);
+ btrfs_abort_transaction(trans, ret);
goto out;
}
cur += this_len;
ret = 0;
else if (ret == 0)
goto process_leaf;
+ else
+ btrfs_abort_transaction(trans, ret);
out:
btrfs_free_path(log_path);
btrfs_release_path(path);
dir_key.objectid = dirid;
dir_key.type = BTRFS_DIR_INDEX_KEY;
log_path = btrfs_alloc_path();
- if (!log_path)
+ if (!log_path) {
+ btrfs_abort_transaction(trans, -ENOMEM);
return -ENOMEM;
+ }
dir = btrfs_iget_logging(dirid, root);
/*
ret = PTR_ERR(dir);
if (ret == -ENOENT)
ret = 0;
+ else
+ btrfs_abort_transaction(trans, ret);
return ret;
}
else {
ret = find_dir_range(log, path, dirid,
&range_start, &range_end);
- if (ret < 0)
+ if (ret < 0) {
+ btrfs_abort_transaction(trans, ret);
goto out;
- else if (ret > 0)
+ } else if (ret > 0) {
break;
+ }
}
dir_key.offset = range_start;
int nritems;
ret = btrfs_search_slot(NULL, root, &dir_key, path,
0, 0);
- if (ret < 0)
+ if (ret < 0) {
+ btrfs_abort_transaction(trans, ret);
goto out;
+ }
nritems = btrfs_header_nritems(path->nodes[0]);
if (path->slots[0] >= nritems) {
ret = btrfs_next_leaf(root, path);
- if (ret == 1)
+ if (ret == 1) {
break;
- else if (ret < 0)
+ } else if (ret < 0) {
+ btrfs_abort_transaction(trans, ret);
goto out;
+ }
}
btrfs_item_key_to_cpu(path->nodes[0], &found_key,
path->slots[0]);
int ret;
ret = btrfs_read_extent_buffer(eb, &check);
- if (ret)
+ if (ret) {
+ btrfs_abort_transaction(trans, ret);
return ret;
+ }
level = btrfs_header_level(eb);
return 0;
path = btrfs_alloc_path();
- if (!path)
+ if (!path) {
+ btrfs_abort_transaction(trans, -ENOMEM);
return -ENOMEM;
+ }
nritems = btrfs_header_nritems(eb);
for (i = 0; i < nritems; i++) {
inode = btrfs_iget_logging(key.objectid, root);
if (IS_ERR(inode)) {
ret = PTR_ERR(inode);
+ btrfs_abort_transaction(trans, ret);
break;
}
from = ALIGN(i_size_read(&inode->vfs_inode),
drop_args.end = (u64)-1;
drop_args.drop_cache = true;
ret = btrfs_drop_extents(trans, root, inode, &drop_args);
- if (!ret) {
+ if (ret) {
+ btrfs_abort_transaction(trans, ret);
+ } else {
inode_sub_bytes(&inode->vfs_inode,
drop_args.bytes_found);
/* Update the inode's nbytes. */
ret = btrfs_update_inode(trans, inode);
+ if (ret)
+ btrfs_abort_transaction(trans, ret);
}
iput(&inode->vfs_inode);
if (ret)