diff options
Diffstat (limited to 'fs/gfs2/inode.c')
-rw-r--r-- | fs/gfs2/inode.c | 103 |
1 files changed, 95 insertions, 8 deletions
diff --git a/fs/gfs2/inode.c b/fs/gfs2/inode.c index b1bf2694fb2b..b5612cbb62a5 100644 --- a/fs/gfs2/inode.c +++ b/fs/gfs2/inode.c | |||
@@ -158,7 +158,6 @@ void gfs2_set_iop(struct inode *inode) | |||
158 | * @sb: The super block | 158 | * @sb: The super block |
159 | * @no_addr: The inode number | 159 | * @no_addr: The inode number |
160 | * @type: The type of the inode | 160 | * @type: The type of the inode |
161 | * @skip_freeing: set this not return an inode if it is currently being freed. | ||
162 | * | 161 | * |
163 | * Returns: A VFS inode, or an error | 162 | * Returns: A VFS inode, or an error |
164 | */ | 163 | */ |
@@ -166,17 +165,14 @@ void gfs2_set_iop(struct inode *inode) | |||
166 | struct inode *gfs2_inode_lookup(struct super_block *sb, | 165 | struct inode *gfs2_inode_lookup(struct super_block *sb, |
167 | unsigned int type, | 166 | unsigned int type, |
168 | u64 no_addr, | 167 | u64 no_addr, |
169 | u64 no_formal_ino, int skip_freeing) | 168 | u64 no_formal_ino) |
170 | { | 169 | { |
171 | struct inode *inode; | 170 | struct inode *inode; |
172 | struct gfs2_inode *ip; | 171 | struct gfs2_inode *ip; |
173 | struct gfs2_glock *io_gl; | 172 | struct gfs2_glock *io_gl; |
174 | int error; | 173 | int error; |
175 | 174 | ||
176 | if (skip_freeing) | 175 | inode = gfs2_iget(sb, no_addr); |
177 | inode = gfs2_iget_skip(sb, no_addr); | ||
178 | else | ||
179 | inode = gfs2_iget(sb, no_addr); | ||
180 | ip = GFS2_I(inode); | 176 | ip = GFS2_I(inode); |
181 | 177 | ||
182 | if (!inode) | 178 | if (!inode) |
@@ -234,11 +230,102 @@ fail_glock: | |||
234 | fail_iopen: | 230 | fail_iopen: |
235 | gfs2_glock_put(io_gl); | 231 | gfs2_glock_put(io_gl); |
236 | fail_put: | 232 | fail_put: |
233 | if (inode->i_state & I_NEW) | ||
234 | ip->i_gl->gl_object = NULL; | ||
235 | gfs2_glock_put(ip->i_gl); | ||
236 | fail: | ||
237 | if (inode->i_state & I_NEW) | ||
238 | iget_failed(inode); | ||
239 | else | ||
240 | iput(inode); | ||
241 | return ERR_PTR(error); | ||
242 | } | ||
243 | |||
244 | /** | ||
245 | * gfs2_process_unlinked_inode - Lookup an unlinked inode for reclamation | ||
246 | * and try to reclaim it by doing iput. | ||
247 | * | ||
248 | * This function assumes no rgrp locks are currently held. | ||
249 | * | ||
250 | * @sb: The super block | ||
251 | * no_addr: The inode number | ||
252 | * | ||
253 | */ | ||
254 | |||
255 | void gfs2_process_unlinked_inode(struct super_block *sb, u64 no_addr) | ||
256 | { | ||
257 | struct gfs2_sbd *sdp; | ||
258 | struct gfs2_inode *ip; | ||
259 | struct gfs2_glock *io_gl; | ||
260 | int error; | ||
261 | struct gfs2_holder gh; | ||
262 | struct inode *inode; | ||
263 | |||
264 | inode = gfs2_iget_skip(sb, no_addr); | ||
265 | |||
266 | if (!inode) | ||
267 | return; | ||
268 | |||
269 | /* If it's not a new inode, someone's using it, so leave it alone. */ | ||
270 | if (!(inode->i_state & I_NEW)) { | ||
271 | iput(inode); | ||
272 | return; | ||
273 | } | ||
274 | |||
275 | ip = GFS2_I(inode); | ||
276 | sdp = GFS2_SB(inode); | ||
277 | ip->i_no_formal_ino = -1; | ||
278 | |||
279 | error = gfs2_glock_get(sdp, no_addr, &gfs2_inode_glops, CREATE, &ip->i_gl); | ||
280 | if (unlikely(error)) | ||
281 | goto fail; | ||
282 | ip->i_gl->gl_object = ip; | ||
283 | |||
284 | error = gfs2_glock_get(sdp, no_addr, &gfs2_iopen_glops, CREATE, &io_gl); | ||
285 | if (unlikely(error)) | ||
286 | goto fail_put; | ||
287 | |||
288 | set_bit(GIF_INVALID, &ip->i_flags); | ||
289 | error = gfs2_glock_nq_init(io_gl, LM_ST_SHARED, LM_FLAG_TRY | GL_EXACT, | ||
290 | &ip->i_iopen_gh); | ||
291 | if (unlikely(error)) | ||
292 | goto fail_iopen; | ||
293 | |||
294 | ip->i_iopen_gh.gh_gl->gl_object = ip; | ||
295 | gfs2_glock_put(io_gl); | ||
296 | |||
297 | inode->i_mode = DT2IF(DT_UNKNOWN); | ||
298 | |||
299 | /* | ||
300 | * We must read the inode in order to work out its type in | ||
301 | * this case. Note that this doesn't happen often as we normally | ||
302 | * know the type beforehand. This code path only occurs during | ||
303 | * unlinked inode recovery (where it is safe to do this glock, | ||
304 | * which is not true in the general case). | ||
305 | */ | ||
306 | error = gfs2_glock_nq_init(ip->i_gl, LM_ST_EXCLUSIVE, LM_FLAG_TRY, | ||
307 | &gh); | ||
308 | if (unlikely(error)) | ||
309 | goto fail_glock; | ||
310 | |||
311 | /* Inode is now uptodate */ | ||
312 | gfs2_glock_dq_uninit(&gh); | ||
313 | gfs2_set_iop(inode); | ||
314 | |||
315 | /* The iput will cause it to be deleted. */ | ||
316 | iput(inode); | ||
317 | return; | ||
318 | |||
319 | fail_glock: | ||
320 | gfs2_glock_dq(&ip->i_iopen_gh); | ||
321 | fail_iopen: | ||
322 | gfs2_glock_put(io_gl); | ||
323 | fail_put: | ||
237 | ip->i_gl->gl_object = NULL; | 324 | ip->i_gl->gl_object = NULL; |
238 | gfs2_glock_put(ip->i_gl); | 325 | gfs2_glock_put(ip->i_gl); |
239 | fail: | 326 | fail: |
240 | iget_failed(inode); | 327 | iget_failed(inode); |
241 | return ERR_PTR(error); | 328 | return; |
242 | } | 329 | } |
243 | 330 | ||
244 | static int gfs2_dinode_in(struct gfs2_inode *ip, const void *buf) | 331 | static int gfs2_dinode_in(struct gfs2_inode *ip, const void *buf) |
@@ -862,7 +949,7 @@ struct inode *gfs2_createi(struct gfs2_holder *ghs, const struct qstr *name, | |||
862 | goto fail_gunlock2; | 949 | goto fail_gunlock2; |
863 | 950 | ||
864 | inode = gfs2_inode_lookup(dir->i_sb, IF2DT(mode), inum.no_addr, | 951 | inode = gfs2_inode_lookup(dir->i_sb, IF2DT(mode), inum.no_addr, |
865 | inum.no_formal_ino, 0); | 952 | inum.no_formal_ino); |
866 | if (IS_ERR(inode)) | 953 | if (IS_ERR(inode)) |
867 | goto fail_gunlock2; | 954 | goto fail_gunlock2; |
868 | 955 | ||