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. |
