diff options
Diffstat (limited to 'fs/xfs/xfs_iget.c')
-rw-r--r-- | fs/xfs/xfs_iget.c | 108 |
1 files changed, 5 insertions, 103 deletions
diff --git a/fs/xfs/xfs_iget.c b/fs/xfs/xfs_iget.c index 8f8b91be2c99..b1ecc6f97ade 100644 --- a/fs/xfs/xfs_iget.c +++ b/fs/xfs/xfs_iget.c | |||
@@ -25,14 +25,10 @@ | |||
25 | #include "xfs_trans.h" | 25 | #include "xfs_trans.h" |
26 | #include "xfs_sb.h" | 26 | #include "xfs_sb.h" |
27 | #include "xfs_ag.h" | 27 | #include "xfs_ag.h" |
28 | #include "xfs_dir2.h" | ||
29 | #include "xfs_dmapi.h" | ||
30 | #include "xfs_mount.h" | 28 | #include "xfs_mount.h" |
31 | #include "xfs_bmap_btree.h" | 29 | #include "xfs_bmap_btree.h" |
32 | #include "xfs_alloc_btree.h" | 30 | #include "xfs_alloc_btree.h" |
33 | #include "xfs_ialloc_btree.h" | 31 | #include "xfs_ialloc_btree.h" |
34 | #include "xfs_dir2_sf.h" | ||
35 | #include "xfs_attr_sf.h" | ||
36 | #include "xfs_dinode.h" | 32 | #include "xfs_dinode.h" |
37 | #include "xfs_inode.h" | 33 | #include "xfs_inode.h" |
38 | #include "xfs_btree.h" | 34 | #include "xfs_btree.h" |
@@ -95,7 +91,7 @@ xfs_inode_alloc( | |||
95 | return ip; | 91 | return ip; |
96 | } | 92 | } |
97 | 93 | ||
98 | STATIC void | 94 | void |
99 | xfs_inode_free( | 95 | xfs_inode_free( |
100 | struct xfs_inode *ip) | 96 | struct xfs_inode *ip) |
101 | { | 97 | { |
@@ -212,7 +208,7 @@ xfs_iget_cache_hit( | |||
212 | ip->i_flags &= ~XFS_INEW; | 208 | ip->i_flags &= ~XFS_INEW; |
213 | ip->i_flags |= XFS_IRECLAIMABLE; | 209 | ip->i_flags |= XFS_IRECLAIMABLE; |
214 | __xfs_inode_set_reclaim_tag(pag, ip); | 210 | __xfs_inode_set_reclaim_tag(pag, ip); |
215 | trace_xfs_iget_reclaim(ip); | 211 | trace_xfs_iget_reclaim_fail(ip); |
216 | goto out_error; | 212 | goto out_error; |
217 | } | 213 | } |
218 | 214 | ||
@@ -227,6 +223,7 @@ xfs_iget_cache_hit( | |||
227 | } else { | 223 | } else { |
228 | /* If the VFS inode is being torn down, pause and try again. */ | 224 | /* If the VFS inode is being torn down, pause and try again. */ |
229 | if (!igrab(inode)) { | 225 | if (!igrab(inode)) { |
226 | trace_xfs_iget_skip(ip); | ||
230 | error = EAGAIN; | 227 | error = EAGAIN; |
231 | goto out_error; | 228 | goto out_error; |
232 | } | 229 | } |
@@ -234,6 +231,7 @@ xfs_iget_cache_hit( | |||
234 | /* We've got a live one. */ | 231 | /* We've got a live one. */ |
235 | spin_unlock(&ip->i_flags_lock); | 232 | spin_unlock(&ip->i_flags_lock); |
236 | read_unlock(&pag->pag_ici_lock); | 233 | read_unlock(&pag->pag_ici_lock); |
234 | trace_xfs_iget_hit(ip); | ||
237 | } | 235 | } |
238 | 236 | ||
239 | if (lock_flags != 0) | 237 | if (lock_flags != 0) |
@@ -242,7 +240,6 @@ xfs_iget_cache_hit( | |||
242 | xfs_iflags_clear(ip, XFS_ISTALE); | 240 | xfs_iflags_clear(ip, XFS_ISTALE); |
243 | XFS_STATS_INC(xs_ig_found); | 241 | XFS_STATS_INC(xs_ig_found); |
244 | 242 | ||
245 | trace_xfs_iget_found(ip); | ||
246 | return 0; | 243 | return 0; |
247 | 244 | ||
248 | out_error: | 245 | out_error: |
@@ -264,7 +261,6 @@ xfs_iget_cache_miss( | |||
264 | { | 261 | { |
265 | struct xfs_inode *ip; | 262 | struct xfs_inode *ip; |
266 | int error; | 263 | int error; |
267 | unsigned long first_index, mask; | ||
268 | xfs_agino_t agino = XFS_INO_TO_AGINO(mp, ino); | 264 | xfs_agino_t agino = XFS_INO_TO_AGINO(mp, ino); |
269 | 265 | ||
270 | ip = xfs_inode_alloc(mp, ino); | 266 | ip = xfs_inode_alloc(mp, ino); |
@@ -275,7 +271,7 @@ xfs_iget_cache_miss( | |||
275 | if (error) | 271 | if (error) |
276 | goto out_destroy; | 272 | goto out_destroy; |
277 | 273 | ||
278 | xfs_itrace_entry(ip); | 274 | trace_xfs_iget_miss(ip); |
279 | 275 | ||
280 | if ((ip->i_d.di_mode == 0) && !(flags & XFS_IGET_CREATE)) { | 276 | if ((ip->i_d.di_mode == 0) && !(flags & XFS_IGET_CREATE)) { |
281 | error = ENOENT; | 277 | error = ENOENT; |
@@ -301,8 +297,6 @@ xfs_iget_cache_miss( | |||
301 | BUG(); | 297 | BUG(); |
302 | } | 298 | } |
303 | 299 | ||
304 | mask = ~(((XFS_INODE_CLUSTER_SIZE(mp) >> mp->m_sb.sb_inodelog)) - 1); | ||
305 | first_index = agino & mask; | ||
306 | write_lock(&pag->pag_ici_lock); | 300 | write_lock(&pag->pag_ici_lock); |
307 | 301 | ||
308 | /* insert the new inode */ | 302 | /* insert the new inode */ |
@@ -321,7 +315,6 @@ xfs_iget_cache_miss( | |||
321 | write_unlock(&pag->pag_ici_lock); | 315 | write_unlock(&pag->pag_ici_lock); |
322 | radix_tree_preload_end(); | 316 | radix_tree_preload_end(); |
323 | 317 | ||
324 | trace_xfs_iget_alloc(ip); | ||
325 | *ipp = ip; | 318 | *ipp = ip; |
326 | return 0; | 319 | return 0; |
327 | 320 | ||
@@ -422,97 +415,6 @@ out_error_or_again: | |||
422 | } | 415 | } |
423 | 416 | ||
424 | /* | 417 | /* |
425 | * Decrement reference count of an inode structure and unlock it. | ||
426 | * | ||
427 | * ip -- the inode being released | ||
428 | * lock_flags -- this parameter indicates the inode's locks to be | ||
429 | * to be released. See the comment on xfs_iunlock() for a list | ||
430 | * of valid values. | ||
431 | */ | ||
432 | void | ||
433 | xfs_iput(xfs_inode_t *ip, | ||
434 | uint lock_flags) | ||
435 | { | ||
436 | xfs_itrace_entry(ip); | ||
437 | xfs_iunlock(ip, lock_flags); | ||
438 | IRELE(ip); | ||
439 | } | ||
440 | |||
441 | /* | ||
442 | * Special iput for brand-new inodes that are still locked | ||
443 | */ | ||
444 | void | ||
445 | xfs_iput_new( | ||
446 | xfs_inode_t *ip, | ||
447 | uint lock_flags) | ||
448 | { | ||
449 | struct inode *inode = VFS_I(ip); | ||
450 | |||
451 | xfs_itrace_entry(ip); | ||
452 | |||
453 | if ((ip->i_d.di_mode == 0)) { | ||
454 | ASSERT(!xfs_iflags_test(ip, XFS_IRECLAIMABLE)); | ||
455 | make_bad_inode(inode); | ||
456 | } | ||
457 | if (inode->i_state & I_NEW) | ||
458 | unlock_new_inode(inode); | ||
459 | if (lock_flags) | ||
460 | xfs_iunlock(ip, lock_flags); | ||
461 | IRELE(ip); | ||
462 | } | ||
463 | |||
464 | /* | ||
465 | * This is called free all the memory associated with an inode. | ||
466 | * It must free the inode itself and any buffers allocated for | ||
467 | * if_extents/if_data and if_broot. It must also free the lock | ||
468 | * associated with the inode. | ||
469 | * | ||
470 | * Note: because we don't initialise everything on reallocation out | ||
471 | * of the zone, we must ensure we nullify everything correctly before | ||
472 | * freeing the structure. | ||
473 | */ | ||
474 | void | ||
475 | xfs_ireclaim( | ||
476 | struct xfs_inode *ip) | ||
477 | { | ||
478 | struct xfs_mount *mp = ip->i_mount; | ||
479 | struct xfs_perag *pag; | ||
480 | xfs_agino_t agino = XFS_INO_TO_AGINO(mp, ip->i_ino); | ||
481 | |||
482 | XFS_STATS_INC(xs_ig_reclaims); | ||
483 | |||
484 | /* | ||
485 | * Remove the inode from the per-AG radix tree. | ||
486 | * | ||
487 | * Because radix_tree_delete won't complain even if the item was never | ||
488 | * added to the tree assert that it's been there before to catch | ||
489 | * problems with the inode life time early on. | ||
490 | */ | ||
491 | pag = xfs_perag_get(mp, XFS_INO_TO_AGNO(mp, ip->i_ino)); | ||
492 | write_lock(&pag->pag_ici_lock); | ||
493 | if (!radix_tree_delete(&pag->pag_ici_root, agino)) | ||
494 | ASSERT(0); | ||
495 | write_unlock(&pag->pag_ici_lock); | ||
496 | xfs_perag_put(pag); | ||
497 | |||
498 | /* | ||
499 | * Here we do an (almost) spurious inode lock in order to coordinate | ||
500 | * with inode cache radix tree lookups. This is because the lookup | ||
501 | * can reference the inodes in the cache without taking references. | ||
502 | * | ||
503 | * We make that OK here by ensuring that we wait until the inode is | ||
504 | * unlocked after the lookup before we go ahead and free it. We get | ||
505 | * both the ilock and the iolock because the code may need to drop the | ||
506 | * ilock one but will still hold the iolock. | ||
507 | */ | ||
508 | xfs_ilock(ip, XFS_ILOCK_EXCL | XFS_IOLOCK_EXCL); | ||
509 | xfs_qm_dqdetach(ip); | ||
510 | xfs_iunlock(ip, XFS_ILOCK_EXCL | XFS_IOLOCK_EXCL); | ||
511 | |||
512 | xfs_inode_free(ip); | ||
513 | } | ||
514 | |||
515 | /* | ||
516 | * This is a wrapper routine around the xfs_ilock() routine | 418 | * This is a wrapper routine around the xfs_ilock() routine |
517 | * used to centralize some grungy code. It is used in places | 419 | * used to centralize some grungy code. It is used in places |
518 | * that wish to lock the inode solely for reading the extents. | 420 | * that wish to lock the inode solely for reading the extents. |