aboutsummaryrefslogtreecommitdiffstats
path: root/fs/xfs/xfs_iget.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/xfs/xfs_iget.c')
-rw-r--r--fs/xfs/xfs_iget.c147
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
98STATIC void 94void
99xfs_inode_free( 95xfs_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
248out_error: 245out_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 */
364int 354int
365xfs_iget( 355xfs_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
390again: 376again:
@@ -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 */
439void
440xfs_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 */
451void
452xfs_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 */
481void
482xfs_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 */
754int 642int
755xfs_isilocked( 643xfs_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