diff options
Diffstat (limited to 'fs/xfs/xfs_iget.c')
-rw-r--r-- | fs/xfs/xfs_iget.c | 147 |
1 files changed, 18 insertions, 129 deletions
diff --git a/fs/xfs/xfs_iget.c b/fs/xfs/xfs_iget.c index 6845db90818f..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: |
@@ -259,24 +256,22 @@ xfs_iget_cache_miss( | |||
259 | xfs_trans_t *tp, | 256 | xfs_trans_t *tp, |
260 | xfs_ino_t ino, | 257 | xfs_ino_t ino, |
261 | struct xfs_inode **ipp, | 258 | struct xfs_inode **ipp, |
262 | xfs_daddr_t bno, | ||
263 | int flags, | 259 | int flags, |
264 | int lock_flags) | 260 | int lock_flags) |
265 | { | 261 | { |
266 | struct xfs_inode *ip; | 262 | struct xfs_inode *ip; |
267 | int error; | 263 | int error; |
268 | unsigned long first_index, mask; | ||
269 | xfs_agino_t agino = XFS_INO_TO_AGINO(mp, ino); | 264 | xfs_agino_t agino = XFS_INO_TO_AGINO(mp, ino); |
270 | 265 | ||
271 | ip = xfs_inode_alloc(mp, ino); | 266 | ip = xfs_inode_alloc(mp, ino); |
272 | if (!ip) | 267 | if (!ip) |
273 | return ENOMEM; | 268 | return ENOMEM; |
274 | 269 | ||
275 | error = xfs_iread(mp, tp, ip, bno, flags); | 270 | error = xfs_iread(mp, tp, ip, flags); |
276 | if (error) | 271 | if (error) |
277 | goto out_destroy; | 272 | goto out_destroy; |
278 | 273 | ||
279 | xfs_itrace_entry(ip); | 274 | trace_xfs_iget_miss(ip); |
280 | 275 | ||
281 | if ((ip->i_d.di_mode == 0) && !(flags & XFS_IGET_CREATE)) { | 276 | if ((ip->i_d.di_mode == 0) && !(flags & XFS_IGET_CREATE)) { |
282 | error = ENOENT; | 277 | error = ENOENT; |
@@ -302,8 +297,6 @@ xfs_iget_cache_miss( | |||
302 | BUG(); | 297 | BUG(); |
303 | } | 298 | } |
304 | 299 | ||
305 | mask = ~(((XFS_INODE_CLUSTER_SIZE(mp) >> mp->m_sb.sb_inodelog)) - 1); | ||
306 | first_index = agino & mask; | ||
307 | write_lock(&pag->pag_ici_lock); | 300 | write_lock(&pag->pag_ici_lock); |
308 | 301 | ||
309 | /* insert the new inode */ | 302 | /* insert the new inode */ |
@@ -322,7 +315,6 @@ xfs_iget_cache_miss( | |||
322 | write_unlock(&pag->pag_ici_lock); | 315 | write_unlock(&pag->pag_ici_lock); |
323 | radix_tree_preload_end(); | 316 | radix_tree_preload_end(); |
324 | 317 | ||
325 | trace_xfs_iget_alloc(ip); | ||
326 | *ipp = ip; | 318 | *ipp = ip; |
327 | return 0; | 319 | return 0; |
328 | 320 | ||
@@ -358,8 +350,6 @@ out_destroy: | |||
358 | * within the file system for the inode being requested. | 350 | * within the file system for the inode being requested. |
359 | * lock_flags -- flags indicating how to lock the inode. See the comment | 351 | * lock_flags -- flags indicating how to lock the inode. See the comment |
360 | * for xfs_ilock() for a list of valid values. | 352 | * for xfs_ilock() for a list of valid values. |
361 | * bno -- the block number starting the buffer containing the inode, | ||
362 | * if known (as by bulkstat), else 0. | ||
363 | */ | 353 | */ |
364 | int | 354 | int |
365 | xfs_iget( | 355 | xfs_iget( |
@@ -368,8 +358,7 @@ xfs_iget( | |||
368 | xfs_ino_t ino, | 358 | xfs_ino_t ino, |
369 | uint flags, | 359 | uint flags, |
370 | uint lock_flags, | 360 | uint lock_flags, |
371 | xfs_inode_t **ipp, | 361 | xfs_inode_t **ipp) |
372 | xfs_daddr_t bno) | ||
373 | { | 362 | { |
374 | xfs_inode_t *ip; | 363 | xfs_inode_t *ip; |
375 | int error; | 364 | int error; |
@@ -382,9 +371,6 @@ xfs_iget( | |||
382 | 371 | ||
383 | /* get the perag structure and ensure that it's inode capable */ | 372 | /* get the perag structure and ensure that it's inode capable */ |
384 | pag = xfs_perag_get(mp, XFS_INO_TO_AGNO(mp, ino)); | 373 | pag = xfs_perag_get(mp, XFS_INO_TO_AGNO(mp, ino)); |
385 | if (!pag->pagi_inodeok) | ||
386 | return EINVAL; | ||
387 | ASSERT(pag->pag_ici_init); | ||
388 | agino = XFS_INO_TO_AGINO(mp, ino); | 374 | agino = XFS_INO_TO_AGINO(mp, ino); |
389 | 375 | ||
390 | again: | 376 | again: |
@@ -400,7 +386,7 @@ again: | |||
400 | read_unlock(&pag->pag_ici_lock); | 386 | read_unlock(&pag->pag_ici_lock); |
401 | XFS_STATS_INC(xs_ig_missed); | 387 | XFS_STATS_INC(xs_ig_missed); |
402 | 388 | ||
403 | error = xfs_iget_cache_miss(mp, pag, tp, ino, &ip, bno, | 389 | error = xfs_iget_cache_miss(mp, pag, tp, ino, &ip, |
404 | flags, lock_flags); | 390 | flags, lock_flags); |
405 | if (error) | 391 | if (error) |
406 | goto out_error_or_again; | 392 | goto out_error_or_again; |
@@ -429,97 +415,6 @@ out_error_or_again: | |||
429 | } | 415 | } |
430 | 416 | ||
431 | /* | 417 | /* |
432 | * Decrement reference count of an inode structure and unlock it. | ||
433 | * | ||
434 | * ip -- the inode being released | ||
435 | * lock_flags -- this parameter indicates the inode's locks to be | ||
436 | * to be released. See the comment on xfs_iunlock() for a list | ||
437 | * of valid values. | ||
438 | */ | ||
439 | void | ||
440 | xfs_iput(xfs_inode_t *ip, | ||
441 | uint lock_flags) | ||
442 | { | ||
443 | xfs_itrace_entry(ip); | ||
444 | xfs_iunlock(ip, lock_flags); | ||
445 | IRELE(ip); | ||
446 | } | ||
447 | |||
448 | /* | ||
449 | * Special iput for brand-new inodes that are still locked | ||
450 | */ | ||
451 | void | ||
452 | xfs_iput_new( | ||
453 | xfs_inode_t *ip, | ||
454 | uint lock_flags) | ||
455 | { | ||
456 | struct inode *inode = VFS_I(ip); | ||
457 | |||
458 | xfs_itrace_entry(ip); | ||
459 | |||
460 | if ((ip->i_d.di_mode == 0)) { | ||
461 | ASSERT(!xfs_iflags_test(ip, XFS_IRECLAIMABLE)); | ||
462 | make_bad_inode(inode); | ||
463 | } | ||
464 | if (inode->i_state & I_NEW) | ||
465 | unlock_new_inode(inode); | ||
466 | if (lock_flags) | ||
467 | xfs_iunlock(ip, lock_flags); | ||
468 | IRELE(ip); | ||
469 | } | ||
470 | |||
471 | /* | ||
472 | * This is called free all the memory associated with an inode. | ||
473 | * It must free the inode itself and any buffers allocated for | ||
474 | * if_extents/if_data and if_broot. It must also free the lock | ||
475 | * associated with the inode. | ||
476 | * | ||
477 | * Note: because we don't initialise everything on reallocation out | ||
478 | * of the zone, we must ensure we nullify everything correctly before | ||
479 | * freeing the structure. | ||
480 | */ | ||
481 | void | ||
482 | xfs_ireclaim( | ||
483 | struct xfs_inode *ip) | ||
484 | { | ||
485 | struct xfs_mount *mp = ip->i_mount; | ||
486 | struct xfs_perag *pag; | ||
487 | xfs_agino_t agino = XFS_INO_TO_AGINO(mp, ip->i_ino); | ||
488 | |||
489 | XFS_STATS_INC(xs_ig_reclaims); | ||
490 | |||
491 | /* | ||
492 | * Remove the inode from the per-AG radix tree. | ||
493 | * | ||
494 | * Because radix_tree_delete won't complain even if the item was never | ||
495 | * added to the tree assert that it's been there before to catch | ||
496 | * problems with the inode life time early on. | ||
497 | */ | ||
498 | pag = xfs_perag_get(mp, XFS_INO_TO_AGNO(mp, ip->i_ino)); | ||
499 | write_lock(&pag->pag_ici_lock); | ||
500 | if (!radix_tree_delete(&pag->pag_ici_root, agino)) | ||
501 | ASSERT(0); | ||
502 | write_unlock(&pag->pag_ici_lock); | ||
503 | xfs_perag_put(pag); | ||
504 | |||
505 | /* | ||
506 | * Here we do an (almost) spurious inode lock in order to coordinate | ||
507 | * with inode cache radix tree lookups. This is because the lookup | ||
508 | * can reference the inodes in the cache without taking references. | ||
509 | * | ||
510 | * We make that OK here by ensuring that we wait until the inode is | ||
511 | * unlocked after the lookup before we go ahead and free it. We get | ||
512 | * both the ilock and the iolock because the code may need to drop the | ||
513 | * ilock one but will still hold the iolock. | ||
514 | */ | ||
515 | xfs_ilock(ip, XFS_ILOCK_EXCL | XFS_IOLOCK_EXCL); | ||
516 | xfs_qm_dqdetach(ip); | ||
517 | xfs_iunlock(ip, XFS_ILOCK_EXCL | XFS_IOLOCK_EXCL); | ||
518 | |||
519 | xfs_inode_free(ip); | ||
520 | } | ||
521 | |||
522 | /* | ||
523 | * This is a wrapper routine around the xfs_ilock() routine | 418 | * This is a wrapper routine around the xfs_ilock() routine |
524 | * used to centralize some grungy code. It is used in places | 419 | * used to centralize some grungy code. It is used in places |
525 | * that wish to lock the inode solely for reading the extents. | 420 | * that wish to lock the inode solely for reading the extents. |
@@ -744,30 +639,24 @@ xfs_ilock_demote( | |||
744 | } | 639 | } |
745 | 640 | ||
746 | #ifdef DEBUG | 641 | #ifdef DEBUG |
747 | /* | ||
748 | * Debug-only routine, without additional rw_semaphore APIs, we can | ||
749 | * now only answer requests regarding whether we hold the lock for write | ||
750 | * (reader state is outside our visibility, we only track writer state). | ||
751 | * | ||
752 | * Note: this means !xfs_isilocked would give false positives, so don't do that. | ||
753 | */ | ||
754 | int | 642 | int |
755 | xfs_isilocked( | 643 | xfs_isilocked( |
756 | xfs_inode_t *ip, | 644 | xfs_inode_t *ip, |
757 | uint lock_flags) | 645 | uint lock_flags) |
758 | { | 646 | { |
759 | if ((lock_flags & (XFS_ILOCK_EXCL|XFS_ILOCK_SHARED)) == | 647 | if (lock_flags & (XFS_ILOCK_EXCL|XFS_ILOCK_SHARED)) { |
760 | XFS_ILOCK_EXCL) { | 648 | if (!(lock_flags & XFS_ILOCK_SHARED)) |
761 | if (!ip->i_lock.mr_writer) | 649 | return !!ip->i_lock.mr_writer; |
762 | return 0; | 650 | return rwsem_is_locked(&ip->i_lock.mr_lock); |
763 | } | 651 | } |
764 | 652 | ||
765 | if ((lock_flags & (XFS_IOLOCK_EXCL|XFS_IOLOCK_SHARED)) == | 653 | if (lock_flags & (XFS_IOLOCK_EXCL|XFS_IOLOCK_SHARED)) { |
766 | XFS_IOLOCK_EXCL) { | 654 | if (!(lock_flags & XFS_IOLOCK_SHARED)) |
767 | if (!ip->i_iolock.mr_writer) | 655 | return !!ip->i_iolock.mr_writer; |
768 | return 0; | 656 | return rwsem_is_locked(&ip->i_iolock.mr_lock); |
769 | } | 657 | } |
770 | 658 | ||
771 | return 1; | 659 | ASSERT(0); |
660 | return 0; | ||
772 | } | 661 | } |
773 | #endif | 662 | #endif |