]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/blame - releases/2.6.32.19/btrfs-avoid-orphan-inodes-cleanup-during-committing-transaction.patch
4.14-stable patches
[thirdparty/kernel/stable-queue.git] / releases / 2.6.32.19 / btrfs-avoid-orphan-inodes-cleanup-during-committing-transaction.patch
CommitLineData
8de80845
GKH
1From 2e4bfab97055aa6acdd0637913bd705c2d6506d6 Mon Sep 17 00:00:00 2001
2From: Yan, Zheng <zheng.yan@oracle.com>
3Date: Thu, 12 Nov 2009 09:37:02 +0000
4Subject: Btrfs: Avoid orphan inodes cleanup during committing transaction
5
6From: Yan, Zheng <zheng.yan@oracle.com>
7
8commit 2e4bfab97055aa6acdd0637913bd705c2d6506d6 upstream.
9
10btrfs_lookup_dentry may trigger orphan cleanup, so it's not good
11to call it while committing a transaction.
12
13Signed-off-by: Yan Zheng <zheng.yan@oracle.com>
14Signed-off-by: Chris Mason <chris.mason@oracle.com>
15Acked-by: Jeff Mahoney <jeffm@suse.com>
16Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
17
18---
19 fs/btrfs/ioctl.c | 29 +++++++++++++++++------------
20 fs/btrfs/transaction.c | 4 ----
21 2 files changed, 17 insertions(+), 16 deletions(-)
22
23--- a/fs/btrfs/ioctl.c
24+++ b/fs/btrfs/ioctl.c
25@@ -237,7 +237,6 @@ static noinline int create_subvol(struct
26 u64 objectid;
27 u64 new_dirid = BTRFS_FIRST_FREE_OBJECTID;
28 u64 index = 0;
29- unsigned long nr = 1;
30
31 /*
32 * 1 - inode item
33@@ -342,24 +341,21 @@ static noinline int create_subvol(struct
34
35 d_instantiate(dentry, btrfs_lookup_dentry(dir, dentry));
36 fail:
37- nr = trans->blocks_used;
38 err = btrfs_commit_transaction(trans, root);
39 if (err && !ret)
40 ret = err;
41
42 btrfs_unreserve_metadata_space(root, 6);
43- btrfs_btree_balance_dirty(root, nr);
44 return ret;
45 }
46
47 static int create_snapshot(struct btrfs_root *root, struct dentry *dentry,
48 char *name, int namelen)
49 {
50+ struct inode *inode;
51 struct btrfs_pending_snapshot *pending_snapshot;
52 struct btrfs_trans_handle *trans;
53- int ret = 0;
54- int err;
55- unsigned long nr = 0;
56+ int ret;
57
58 if (!root->ref_cows)
59 return -EINVAL;
60@@ -372,20 +368,20 @@ static int create_snapshot(struct btrfs_
61 */
62 ret = btrfs_reserve_metadata_space(root, 6);
63 if (ret)
64- goto fail_unlock;
65+ goto fail;
66
67 pending_snapshot = kzalloc(sizeof(*pending_snapshot), GFP_NOFS);
68 if (!pending_snapshot) {
69 ret = -ENOMEM;
70 btrfs_unreserve_metadata_space(root, 6);
71- goto fail_unlock;
72+ goto fail;
73 }
74 pending_snapshot->name = kmalloc(namelen + 1, GFP_NOFS);
75 if (!pending_snapshot->name) {
76 ret = -ENOMEM;
77 kfree(pending_snapshot);
78 btrfs_unreserve_metadata_space(root, 6);
79- goto fail_unlock;
80+ goto fail;
81 }
82 memcpy(pending_snapshot->name, name, namelen);
83 pending_snapshot->name[namelen] = '\0';
84@@ -395,10 +391,19 @@ static int create_snapshot(struct btrfs_
85 pending_snapshot->root = root;
86 list_add(&pending_snapshot->list,
87 &trans->transaction->pending_snapshots);
88- err = btrfs_commit_transaction(trans, root);
89+ ret = btrfs_commit_transaction(trans, root);
90+ BUG_ON(ret);
91+ btrfs_unreserve_metadata_space(root, 6);
92
93-fail_unlock:
94- btrfs_btree_balance_dirty(root, nr);
95+ inode = btrfs_lookup_dentry(dentry->d_parent->d_inode, dentry);
96+ if (IS_ERR(inode)) {
97+ ret = PTR_ERR(inode);
98+ goto fail;
99+ }
100+ BUG_ON(!inode);
101+ d_instantiate(dentry, inode);
102+ ret = 0;
103+fail:
104 return ret;
105 }
106
107--- a/fs/btrfs/transaction.c
108+++ b/fs/btrfs/transaction.c
109@@ -796,7 +796,6 @@ static noinline int create_pending_snaps
110 memcpy(&pending->root_key, &key, sizeof(key));
111 fail:
112 kfree(new_root_item);
113- btrfs_unreserve_metadata_space(root, 6);
114 return ret;
115 }
116
117@@ -808,7 +807,6 @@ static noinline int finish_pending_snaps
118 u64 index = 0;
119 struct btrfs_trans_handle *trans;
120 struct inode *parent_inode;
121- struct inode *inode;
122 struct btrfs_root *parent_root;
123
124 parent_inode = pending->dentry->d_parent->d_inode;
125@@ -840,8 +838,6 @@ static noinline int finish_pending_snaps
126
127 BUG_ON(ret);
128
129- inode = btrfs_lookup_dentry(parent_inode, pending->dentry);
130- d_instantiate(pending->dentry, inode);
131 fail:
132 btrfs_end_transaction(trans, fs_info->fs_root);
133 return ret;