@@ -1131,8 +1131,10 @@ static void btrfs_async_run_delayed_node_done(struct btrfs_work *work)
root = delayed_node->root;
trans = btrfs_join_transaction(root);
- if (IS_ERR(trans))
+ if (IS_ERR(trans)) {
+ btrfs_abort_transaction(root, PTR_ERR(trans));
goto free_path;
+ }
ret = btrfs_insert_delayed_items(trans, path, root, delayed_node);
if (!ret)
@@ -2478,14 +2478,18 @@ int btrfs_commit_super(struct btrfs_root *root)
up_write(&root->fs_info->cleanup_work_sem);
trans = btrfs_join_transaction(root);
- if (IS_ERR(trans))
+ if (IS_ERR(trans)) {
+ btrfs_abort_transaction(root, PTR_ERR(trans));
return PTR_ERR(trans);
+ }
ret = btrfs_commit_transaction(trans, root);
BUG_ON(ret);
/* run commit again to drop the original snapshot */
trans = btrfs_join_transaction(root);
- if (IS_ERR(trans))
+ if (IS_ERR(trans)) {
+ btrfs_abort_transaction(root, PTR_ERR(trans));
return PTR_ERR(trans);
+ }
btrfs_commit_transaction(trans, root);
ret = btrfs_write_and_wait_transaction(NULL, root);
BUG_ON(ret);
@@ -3068,8 +3068,10 @@ again:
alloc:
alloc_target = btrfs_get_alloc_profile(root, 1);
trans = btrfs_join_transaction(root);
- if (IS_ERR(trans))
+ if (IS_ERR(trans)) {
+ btrfs_abort_transaction(root, PTR_ERR(trans));
return PTR_ERR(trans);
+ }
ret = do_chunk_alloc(trans, root->fs_info->extent_root,
bytes + 2 * 1024 * 1024,
@@ -3104,8 +3106,10 @@ commit_trans:
!atomic_read(&root->fs_info->open_ioctl_trans)) {
committed = 1;
trans = btrfs_join_transaction(root);
- if (IS_ERR(trans))
+ if (IS_ERR(trans)) {
+ btrfs_abort_transaction(root, PTR_ERR(trans));
return PTR_ERR(trans);
+ }
ret = btrfs_commit_transaction(trans, root);
if (ret)
return ret;
@@ -3483,8 +3487,10 @@ again:
ret = -ENOSPC;
trans = btrfs_join_transaction(root);
- if (IS_ERR(trans))
+ if (IS_ERR(trans)) {
+ btrfs_abort_transaction(root, PTR_ERR(trans));
goto out;
+ }
ret = btrfs_commit_transaction(trans, root);
if (!ret) {
trans = NULL;
@@ -6568,7 +6574,10 @@ int btrfs_set_block_group_ro(struct btrfs_root *root,
BUG_ON(cache->ro);
trans = btrfs_join_transaction(root);
- BUG_ON(IS_ERR(trans));
+ if (IS_ERR(trans)) {
+ btrfs_abort_transaction(root, PTR_ERR(trans));
+ return PTR_ERR(trans);
+ }
alloc_flags = update_block_group_flags(root, cache->flags);
if (alloc_flags != cache->flags)
@@ -4274,8 +4274,10 @@ int btrfs_write_inode(struct inode *inode, struct writeback_control *wbc)
trans = btrfs_join_transaction_nolock(root);
else
trans = btrfs_join_transaction(root);
- if (IS_ERR(trans))
+ if (IS_ERR(trans)) {
+ btrfs_abort_transaction(root, PTR_ERR(trans));
return PTR_ERR(trans);
+ }
if (nolock)
ret = btrfs_end_transaction_nolock(trans, root);
else
@@ -5116,8 +5118,11 @@ again:
btrfs_release_path(path);
trans = btrfs_join_transaction(root);
- if (IS_ERR(trans))
+ if (IS_ERR(trans)) {
+ btrfs_abort_transaction(root,
+ PTR_ERR(trans));
return ERR_CAST(trans);
+ }
goto again;
}
map = kmap(page);
@@ -5360,8 +5365,10 @@ static struct extent_map *btrfs_new_extent_direct(struct inode *inode,
}
trans = btrfs_join_transaction(root);
- if (IS_ERR(trans))
+ if (IS_ERR(trans)) {
+ btrfs_abort_transaction(root, PTR_ERR(trans));
return ERR_CAST(trans);
+ }
if (start <= BTRFS_I(inode)->disk_i_size && len < 64 * 1024)
btrfs_add_inode_defrag(trans, inode);
@@ -5737,6 +5744,7 @@ again:
trans = btrfs_join_transaction(root);
if (IS_ERR(trans)) {
err = -ENOMEM;
+ btrfs_abort_transaction(root, err);
goto out;
}
trans->block_rsv = &root->fs_info->delalloc_block_rsv;
@@ -244,7 +244,12 @@ static int btrfs_ioctl_setflags(struct file *file, void __user *arg)
}
trans = btrfs_join_transaction(root);
- BUG_ON(IS_ERR(trans));
+ if (IS_ERR(trans)) {
+ mnt_drop_write(file->f_path.mnt);
+ ret = PTR_ERR(trans);
+ btrfs_abort_transaction(root, ret);
+ goto out_unlock;
+ }
ret = btrfs_update_inode(trans, root, inode);
BUG_ON(ret);
@@ -2160,6 +2160,7 @@ again:
if (!err)
btrfs_block_rsv_release(rc->extent_root,
rc->block_rsv, num_bytes);
+ btrfs_abort_transaction(rc->extent_root, PTR_ERR(trans));
return PTR_ERR(trans);
}
@@ -3243,6 +3244,7 @@ truncate:
if (IS_ERR(trans)) {
btrfs_free_path(path);
ret = PTR_ERR(trans);
+ btrfs_abort_transaction(root, ret);
goto out;
}
@@ -3840,9 +3842,10 @@ restart:
/* get rid of pinned extents */
trans = btrfs_join_transaction(rc->extent_root);
- if (IS_ERR(trans))
+ if (IS_ERR(trans)) {
err = PTR_ERR(trans);
- else
+ btrfs_abort_transaction(rc->extent_root, err);
+ } else
btrfs_commit_transaction(trans, rc->extent_root);
out_free:
btrfs_free_block_rsv(rc->extent_root, rc->block_rsv);
@@ -4169,6 +4172,7 @@ int btrfs_recover_relocation(struct btrfs_root *root)
if (IS_ERR(trans)) {
unset_reloc_control(rc);
err = PTR_ERR(trans);
+ btrfs_abort_transaction(rc->extent_root, err);
goto out_free;
}
@@ -4200,9 +4204,10 @@ int btrfs_recover_relocation(struct btrfs_root *root)
unset_reloc_control(rc);
trans = btrfs_join_transaction(rc->extent_root);
- if (IS_ERR(trans))
+ if (IS_ERR(trans)) {
err = PTR_ERR(trans);
- else
+ btrfs_abort_transaction(rc->extent_root, err);
+ } else
btrfs_commit_transaction(trans, rc->extent_root);
out_free:
kfree(rc);
@@ -1103,6 +1103,7 @@ int btrfs_commit_transaction_async(struct btrfs_trans_handle *trans,
if (IS_ERR(ac->newtrans)) {
int err = PTR_ERR(ac->newtrans);
kfree(ac);
+ btrfs_abort_transaction(root, err);
return err;
}
When btrfs_join_transaction()/btrfs_join_transaction_nolock() fails, we should call btrfs_std_error() properly for filesystem to readonly. Signed-off-by: Tsutomu Itoh <t-itoh@jp.fujitsu.com> --- This patch is dependent on http://marc.info/?l=linux-btrfs&m=130761239706076&w=2 (it is necessary to define btrfs_abort_transaction function) fs/btrfs/delayed-inode.c | 4 +++- fs/btrfs/disk-io.c | 8 ++++++-- fs/btrfs/extent-tree.c | 17 +++++++++++++---- fs/btrfs/inode.c | 14 +++++++++++--- fs/btrfs/ioctl.c | 7 ++++++- fs/btrfs/relocation.c | 13 +++++++++---- fs/btrfs/transaction.c | 1 + 7 files changed, 49 insertions(+), 15 deletions(-) -- To unsubscribe from this list: send the line "unsubscribe linux-btrfs" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html