Btrfs: release subvolume's block_rsv before transaction commit
authorLiu Bo <bo.li.liu@oracle.com>
Thu, 9 Jan 2014 06:57:06 +0000 (14:57 +0800)
committerChris Mason <clm@fb.com>
Tue, 28 Jan 2014 21:20:29 +0000 (13:20 -0800)
We don't have to keep subvolume's block_rsv during transaction commit,
and within transaction commit, we may also need the free space reclaimed
from this block_rsv to process delayed refs.

Signed-off-by: Liu Bo <bo.li.liu@oracle.com>
Signed-off-by: Josef Bacik <jbacik@fb.com>
Signed-off-by: Chris Mason <clm@fb.com>
fs/btrfs/ioctl.c

index 3970f32b2b8076a4116295a12598f47b241c31c3..332b624e25db2b7c058a33b02957a8ab856c0792 100644 (file)
@@ -436,7 +436,9 @@ static noinline int create_subvol(struct inode *dir,
        trans = btrfs_start_transaction(root, 0);
        if (IS_ERR(trans)) {
                ret = PTR_ERR(trans);
-               goto out;
+               btrfs_subvolume_release_metadata(root, &block_rsv,
+                                                qgroup_reserved);
+               return ret;
        }
        trans->block_rsv = &block_rsv;
        trans->bytes_reserved = block_rsv.size;
@@ -561,6 +563,8 @@ static noinline int create_subvol(struct inode *dir,
 fail:
        trans->block_rsv = NULL;
        trans->bytes_reserved = 0;
+       btrfs_subvolume_release_metadata(root, &block_rsv, qgroup_reserved);
+
        if (async_transid) {
                *async_transid = trans->transid;
                err = btrfs_commit_transaction_async(trans, root, 1);
@@ -574,14 +578,10 @@ fail:
 
        if (!ret) {
                inode = btrfs_lookup_dentry(dir, dentry);
-               if (IS_ERR(inode)) {
-                       ret = PTR_ERR(inode);
-                       goto out;
-               }
+               if (IS_ERR(inode))
+                       return PTR_ERR(inode);
                d_instantiate(dentry, inode);
        }
-out:
-       btrfs_subvolume_release_metadata(root, &block_rsv, qgroup_reserved);
        return ret;
 }