]>
Commit | Line | Data |
---|---|---|
2cb7cef9 BS |
1 | From: Tiger Yang <tiger.yang@oracle.com> |
2 | Date: Fri, 14 Nov 2008 11:15:44 +0800 | |
3 | Subject: ocfs2: move new inode allocation out of the transaction | |
4 | Patch-mainline: 2.6.29 | |
5 | ||
6 | Move out inode allocation from ocfs2_mknod_locked() because | |
7 | vfs_dq_init() must be called outside of a transaction. | |
8 | ||
9 | Signed-off-by: Jan Kara <jack@suse.cz> | |
10 | Signed-off-by: Tiger Yang <tiger.yang@oracle.com> | |
11 | Signed-off-by: Mark Fasheh <mfasheh@suse.com> | |
12 | --- | |
13 | fs/ocfs2/namei.c | 108 ++++++++++++++++++++++++++++++++---------------------- | |
14 | 1 files changed, 64 insertions(+), 44 deletions(-) | |
15 | ||
16 | diff --git a/fs/ocfs2/namei.c b/fs/ocfs2/namei.c | |
17 | index 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 | -- | |
254 | 1.5.6 | |
255 |