]> git.ipfire.org Git - ipfire-2.x.git/blame - src/patches/suse-2.6.27.39/patches.suse/ocfs2-move-new-inode-allocation-out-of-the-transact.patch
Imported linux-2.6.27.39 suse/xen patches.
[ipfire-2.x.git] / src / patches / suse-2.6.27.39 / patches.suse / ocfs2-move-new-inode-allocation-out-of-the-transact.patch
CommitLineData
2cb7cef9
BS
1From: Tiger Yang <tiger.yang@oracle.com>
2Date: Fri, 14 Nov 2008 11:15:44 +0800
3Subject: ocfs2: move new inode allocation out of the transaction
4Patch-mainline: 2.6.29
5
6Move out inode allocation from ocfs2_mknod_locked() because
7vfs_dq_init() must be called outside of a transaction.
8
9Signed-off-by: Jan Kara <jack@suse.cz>
10Signed-off-by: Tiger Yang <tiger.yang@oracle.com>
11Signed-off-by: Mark Fasheh <mfasheh@suse.com>
12---
13 fs/ocfs2/namei.c | 108 ++++++++++++++++++++++++++++++++----------------------
14 1 files changed, 64 insertions(+), 44 deletions(-)
15
16diff --git a/fs/ocfs2/namei.c b/fs/ocfs2/namei.c
17index 2545e74..e8ff0ba 100644
18--- a/fs/ocfs2/namei.c
19+++ b/fs/ocfs2/namei.c
20@@ -66,12 +66,12 @@
21
22 static int ocfs2_mknod_locked(struct ocfs2_super *osb,
23 struct inode *dir,
24- struct dentry *dentry, int mode,
25+ struct inode *inode,
26+ struct dentry *dentry,
27 dev_t dev,
28 struct buffer_head **new_fe_bh,
29 struct buffer_head *parent_fe_bh,
30 handle_t *handle,
31- struct inode **ret_inode,
32 struct ocfs2_alloc_context *inode_ac);
33
34 static int ocfs2_prepare_orphan_dir(struct ocfs2_super *osb,
35@@ -186,6 +186,34 @@ bail:
36 return ret;
37 }
38
39+static struct inode *ocfs2_get_init_inode(struct inode *dir, int mode)
40+{
41+ struct inode *inode;
42+
43+ inode = new_inode(dir->i_sb);
44+ if (!inode) {
45+ mlog(ML_ERROR, "new_inode failed!\n");
46+ return NULL;
47+ }
48+
49+ /* populate as many fields early on as possible - many of
50+ * these are used by the support functions here and in
51+ * callers. */
52+ if (S_ISDIR(mode))
53+ inode->i_nlink = 2;
54+ else
55+ inode->i_nlink = 1;
56+ inode->i_uid = current->fsuid;
57+ if (dir->i_mode & S_ISGID) {
58+ inode->i_gid = dir->i_gid;
59+ if (S_ISDIR(mode))
60+ mode |= S_ISGID;
61+ } else
62+ inode->i_gid = current->fsgid;
63+ inode->i_mode = mode;
64+ return inode;
65+}
66+
67 static int ocfs2_mknod(struct inode *dir,
68 struct dentry *dentry,
69 int mode,
70@@ -250,6 +278,13 @@ static int ocfs2_mknod(struct inode *dir,
71 goto leave;
72 }
73
74+ inode = ocfs2_get_init_inode(dir, mode);
75+ if (!inode) {
76+ status = -ENOMEM;
77+ mlog_errno(status);
78+ goto leave;
79+ }
80+
81 /* Reserve a cluster if creating an extent based directory. */
82 if (S_ISDIR(mode) && !ocfs2_supports_inline_data(osb)) {
83 status = ocfs2_reserve_clusters(osb, 1, &data_ac);
84@@ -269,9 +304,9 @@ static int ocfs2_mknod(struct inode *dir,
85 }
86
87 /* do the real work now. */
88- status = ocfs2_mknod_locked(osb, dir, dentry, mode, dev,
89+ status = ocfs2_mknod_locked(osb, dir, inode, dentry, dev,
90 &new_fe_bh, parent_fe_bh, handle,
91- &inode, inode_ac);
92+ inode_ac);
93 if (status < 0) {
94 mlog_errno(status);
95 goto leave;
96@@ -332,8 +367,10 @@ leave:
97 brelse(de_bh);
98 brelse(parent_fe_bh);
99
100- if ((status < 0) && inode)
101+ if ((status < 0) && inode) {
102+ clear_nlink(inode);
103 iput(inode);
104+ }
105
106 if (inode_ac)
107 ocfs2_free_alloc_context(inode_ac);
108@@ -348,12 +385,12 @@ leave:
109
110 static int ocfs2_mknod_locked(struct ocfs2_super *osb,
111 struct inode *dir,
112- struct dentry *dentry, int mode,
113+ struct inode *inode,
114+ struct dentry *dentry,
115 dev_t dev,
116 struct buffer_head **new_fe_bh,
117 struct buffer_head *parent_fe_bh,
118 handle_t *handle,
119- struct inode **ret_inode,
120 struct ocfs2_alloc_context *inode_ac)
121 {
122 int status = 0;
123@@ -361,14 +398,12 @@ static int ocfs2_mknod_locked(struct ocfs2_super *osb,
124 struct ocfs2_extent_list *fel;
125 u64 fe_blkno = 0;
126 u16 suballoc_bit;
127- struct inode *inode = NULL;
128
129- mlog_entry("(0x%p, 0x%p, %d, %lu, '%.*s')\n", dir, dentry, mode,
130- (unsigned long)dev, dentry->d_name.len,
131+ mlog_entry("(0x%p, 0x%p, %d, %lu, '%.*s')\n", dir, dentry,
132+ inode->i_mode, (unsigned long)dev, dentry->d_name.len,
133 dentry->d_name.name);
134
135 *new_fe_bh = NULL;
136- *ret_inode = NULL;
137
138 status = ocfs2_claim_new_inode(osb, handle, inode_ac, &suballoc_bit,
139 &fe_blkno);
140@@ -377,23 +412,11 @@ static int ocfs2_mknod_locked(struct ocfs2_super *osb,
141 goto leave;
142 }
143
144- inode = new_inode(dir->i_sb);
145- if (!inode) {
146- status = -ENOMEM;
147- mlog(ML_ERROR, "new_inode failed!\n");
148- goto leave;
149- }
150-
151 /* populate as many fields early on as possible - many of
152 * these are used by the support functions here and in
153 * callers. */
154 inode->i_ino = ino_from_blkno(osb->sb, fe_blkno);
155 OCFS2_I(inode)->ip_blkno = fe_blkno;
156- if (S_ISDIR(mode))
157- inode->i_nlink = 2;
158- else
159- inode->i_nlink = 1;
160- inode->i_mode = mode;
161 spin_lock(&osb->osb_lock);
162 inode->i_generation = osb->s_next_generation++;
163 spin_unlock(&osb->osb_lock);
164@@ -421,17 +444,11 @@ static int ocfs2_mknod_locked(struct ocfs2_super *osb,
165 fe->i_blkno = cpu_to_le64(fe_blkno);
166 fe->i_suballoc_bit = cpu_to_le16(suballoc_bit);
167 fe->i_suballoc_slot = cpu_to_le16(inode_ac->ac_alloc_slot);
168- fe->i_uid = cpu_to_le32(current->fsuid);
169- if (dir->i_mode & S_ISGID) {
170- fe->i_gid = cpu_to_le32(dir->i_gid);
171- if (S_ISDIR(mode))
172- mode |= S_ISGID;
173- } else
174- fe->i_gid = cpu_to_le32(current->fsgid);
175- fe->i_mode = cpu_to_le16(mode);
176- if (S_ISCHR(mode) || S_ISBLK(mode))
177+ fe->i_uid = cpu_to_le32(inode->i_uid);
178+ fe->i_gid = cpu_to_le32(inode->i_gid);
179+ fe->i_mode = cpu_to_le16(inode->i_mode);
180+ if (S_ISCHR(inode->i_mode) || S_ISBLK(inode->i_mode))
181 fe->id1.dev1.i_rdev = cpu_to_le64(huge_encode_dev(dev));
182-
183 fe->i_links_count = cpu_to_le16(inode->i_nlink);
184
185 fe->i_last_eb_blk = 0;
186@@ -446,7 +463,7 @@ static int ocfs2_mknod_locked(struct ocfs2_super *osb,
187 /*
188 * If supported, directories start with inline data.
189 */
190- if (S_ISDIR(mode) && ocfs2_supports_inline_data(osb)) {
191+ if (S_ISDIR(inode->i_mode) && ocfs2_supports_inline_data(osb)) {
192 u16 feat = le16_to_cpu(fe->i_dyn_features);
193
194 fe->i_dyn_features = cpu_to_le16(feat | OCFS2_INLINE_DATA_FL);
195@@ -484,17 +501,12 @@ static int ocfs2_mknod_locked(struct ocfs2_super *osb,
196 status = 0; /* error in ocfs2_create_new_inode_locks is not
197 * critical */
198
199- *ret_inode = inode;
200 leave:
201 if (status < 0) {
202 if (*new_fe_bh) {
203 brelse(*new_fe_bh);
204 *new_fe_bh = NULL;
205 }
206- if (inode) {
207- clear_nlink(inode);
208- iput(inode);
209- }
210 }
211
212 mlog_exit(status);
213@@ -1542,6 +1554,13 @@ static int ocfs2_symlink(struct inode *dir,
214 goto bail;
215 }
216
217+ inode = ocfs2_get_init_inode(dir, S_IFLNK | S_IRWXUGO);
218+ if (!inode) {
219+ status = -ENOMEM;
220+ mlog_errno(status);
221+ goto bail;
222+ }
223+
224 /* don't reserve bitmap space for fast symlinks. */
225 if (l > ocfs2_fast_symlink_chars(sb)) {
226 status = ocfs2_reserve_clusters(osb, 1, &data_ac);
227@@ -1560,10 +1579,9 @@ static int ocfs2_symlink(struct inode *dir,
228 goto bail;
229 }
230
231- status = ocfs2_mknod_locked(osb, dir, dentry,
232- S_IFLNK | S_IRWXUGO, 0,
233- &new_fe_bh, parent_fe_bh, handle,
234- &inode, inode_ac);
235+ status = ocfs2_mknod_locked(osb, dir, inode, dentry,
236+ 0, &new_fe_bh, parent_fe_bh, handle,
237+ inode_ac);
238 if (status < 0) {
239 mlog_errno(status);
240 goto bail;
241@@ -1644,8 +1662,10 @@ bail:
242 ocfs2_free_alloc_context(inode_ac);
243 if (data_ac)
244 ocfs2_free_alloc_context(data_ac);
245- if ((status < 0) && inode)
246+ if ((status < 0) && inode) {
247+ clear_nlink(inode);
248 iput(inode);
249+ }
250
251 mlog_exit(status);
252
253--
2541.5.6
255