diff options
Diffstat (limited to 'fs/gfs2/inode.c')
-rw-r--r-- | fs/gfs2/inode.c | 54 |
1 files changed, 29 insertions, 25 deletions
diff --git a/fs/gfs2/inode.c b/fs/gfs2/inode.c index 51d8061fa07a..b5612cbb62a5 100644 --- a/fs/gfs2/inode.c +++ b/fs/gfs2/inode.c | |||
@@ -242,34 +242,38 @@ fail: | |||
242 | } | 242 | } |
243 | 243 | ||
244 | /** | 244 | /** |
245 | * gfs2_unlinked_inode_lookup - Lookup an unlinked inode for reclamation | 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 | * | ||
246 | * @sb: The super block | 250 | * @sb: The super block |
247 | * no_addr: The inode number | 251 | * no_addr: The inode number |
248 | * @@inode: A pointer to the inode found, if any | ||
249 | * | 252 | * |
250 | * Returns: 0 and *inode if no errors occurred. If an error occurs, | ||
251 | * the resulting *inode may or may not be NULL. | ||
252 | */ | 253 | */ |
253 | 254 | ||
254 | int gfs2_unlinked_inode_lookup(struct super_block *sb, u64 no_addr, | 255 | void gfs2_process_unlinked_inode(struct super_block *sb, u64 no_addr) |
255 | struct inode **inode) | ||
256 | { | 256 | { |
257 | struct gfs2_sbd *sdp; | 257 | struct gfs2_sbd *sdp; |
258 | struct gfs2_inode *ip; | 258 | struct gfs2_inode *ip; |
259 | struct gfs2_glock *io_gl; | 259 | struct gfs2_glock *io_gl; |
260 | int error; | 260 | int error; |
261 | struct gfs2_holder gh; | 261 | struct gfs2_holder gh; |
262 | struct inode *inode; | ||
262 | 263 | ||
263 | *inode = gfs2_iget_skip(sb, no_addr); | 264 | inode = gfs2_iget_skip(sb, no_addr); |
264 | 265 | ||
265 | if (!(*inode)) | 266 | if (!inode) |
266 | return -ENOBUFS; | 267 | return; |
267 | 268 | ||
268 | if (!((*inode)->i_state & I_NEW)) | 269 | /* If it's not a new inode, someone's using it, so leave it alone. */ |
269 | return -ENOBUFS; | 270 | if (!(inode->i_state & I_NEW)) { |
271 | iput(inode); | ||
272 | return; | ||
273 | } | ||
270 | 274 | ||
271 | ip = GFS2_I(*inode); | 275 | ip = GFS2_I(inode); |
272 | sdp = GFS2_SB(*inode); | 276 | sdp = GFS2_SB(inode); |
273 | ip->i_no_formal_ino = -1; | 277 | ip->i_no_formal_ino = -1; |
274 | 278 | ||
275 | error = gfs2_glock_get(sdp, no_addr, &gfs2_inode_glops, CREATE, &ip->i_gl); | 279 | error = gfs2_glock_get(sdp, no_addr, &gfs2_inode_glops, CREATE, &ip->i_gl); |
@@ -284,15 +288,13 @@ int gfs2_unlinked_inode_lookup(struct super_block *sb, u64 no_addr, | |||
284 | set_bit(GIF_INVALID, &ip->i_flags); | 288 | set_bit(GIF_INVALID, &ip->i_flags); |
285 | error = gfs2_glock_nq_init(io_gl, LM_ST_SHARED, LM_FLAG_TRY | GL_EXACT, | 289 | error = gfs2_glock_nq_init(io_gl, LM_ST_SHARED, LM_FLAG_TRY | GL_EXACT, |
286 | &ip->i_iopen_gh); | 290 | &ip->i_iopen_gh); |
287 | if (unlikely(error)) { | 291 | if (unlikely(error)) |
288 | if (error == GLR_TRYFAILED) | ||
289 | error = 0; | ||
290 | goto fail_iopen; | 292 | goto fail_iopen; |
291 | } | 293 | |
292 | ip->i_iopen_gh.gh_gl->gl_object = ip; | 294 | ip->i_iopen_gh.gh_gl->gl_object = ip; |
293 | gfs2_glock_put(io_gl); | 295 | gfs2_glock_put(io_gl); |
294 | 296 | ||
295 | (*inode)->i_mode = DT2IF(DT_UNKNOWN); | 297 | inode->i_mode = DT2IF(DT_UNKNOWN); |
296 | 298 | ||
297 | /* | 299 | /* |
298 | * We must read the inode in order to work out its type in | 300 | * We must read the inode in order to work out its type in |
@@ -303,16 +305,17 @@ int gfs2_unlinked_inode_lookup(struct super_block *sb, u64 no_addr, | |||
303 | */ | 305 | */ |
304 | error = gfs2_glock_nq_init(ip->i_gl, LM_ST_EXCLUSIVE, LM_FLAG_TRY, | 306 | error = gfs2_glock_nq_init(ip->i_gl, LM_ST_EXCLUSIVE, LM_FLAG_TRY, |
305 | &gh); | 307 | &gh); |
306 | if (unlikely(error)) { | 308 | if (unlikely(error)) |
307 | if (error == GLR_TRYFAILED) | ||
308 | error = 0; | ||
309 | goto fail_glock; | 309 | goto fail_glock; |
310 | } | 310 | |
311 | /* Inode is now uptodate */ | 311 | /* Inode is now uptodate */ |
312 | gfs2_glock_dq_uninit(&gh); | 312 | gfs2_glock_dq_uninit(&gh); |
313 | gfs2_set_iop(*inode); | 313 | gfs2_set_iop(inode); |
314 | |||
315 | /* The iput will cause it to be deleted. */ | ||
316 | iput(inode); | ||
317 | return; | ||
314 | 318 | ||
315 | return 0; | ||
316 | fail_glock: | 319 | fail_glock: |
317 | gfs2_glock_dq(&ip->i_iopen_gh); | 320 | gfs2_glock_dq(&ip->i_iopen_gh); |
318 | fail_iopen: | 321 | fail_iopen: |
@@ -321,7 +324,8 @@ fail_put: | |||
321 | ip->i_gl->gl_object = NULL; | 324 | ip->i_gl->gl_object = NULL; |
322 | gfs2_glock_put(ip->i_gl); | 325 | gfs2_glock_put(ip->i_gl); |
323 | fail: | 326 | fail: |
324 | return error; | 327 | iget_failed(inode); |
328 | return; | ||
325 | } | 329 | } |
326 | 330 | ||
327 | 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) |