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.c132
1 files changed, 28 insertions, 104 deletions
diff --git a/fs/xfs/xfs_iget.c b/fs/xfs/xfs_iget.c
index 80e526489be5..fa402a6bbbcf 100644
--- a/fs/xfs/xfs_iget.c
+++ b/fs/xfs/xfs_iget.c
@@ -43,7 +43,7 @@
43#include "xfs_inode_item.h" 43#include "xfs_inode_item.h"
44#include "xfs_bmap.h" 44#include "xfs_bmap.h"
45#include "xfs_btree_trace.h" 45#include "xfs_btree_trace.h"
46#include "xfs_dir2_trace.h" 46#include "xfs_trace.h"
47 47
48 48
49/* 49/*
@@ -73,6 +73,9 @@ xfs_inode_alloc(
73 ASSERT(atomic_read(&ip->i_pincount) == 0); 73 ASSERT(atomic_read(&ip->i_pincount) == 0);
74 ASSERT(!spin_is_locked(&ip->i_flags_lock)); 74 ASSERT(!spin_is_locked(&ip->i_flags_lock));
75 ASSERT(completion_done(&ip->i_flush)); 75 ASSERT(completion_done(&ip->i_flush));
76 ASSERT(!rwsem_is_locked(&ip->i_iolock.mr_lock));
77
78 mrlock_init(&ip->i_iolock, MRLOCK_BARRIER, "xfsio", ip->i_ino);
76 79
77 /* initialise the xfs inode */ 80 /* initialise the xfs inode */
78 ip->i_ino = ino; 81 ip->i_ino = ino;
@@ -87,30 +90,8 @@ xfs_inode_alloc(
87 ip->i_size = 0; 90 ip->i_size = 0;
88 ip->i_new_size = 0; 91 ip->i_new_size = 0;
89 92
90 /*
91 * Initialize inode's trace buffers.
92 */
93#ifdef XFS_INODE_TRACE
94 ip->i_trace = ktrace_alloc(INODE_TRACE_SIZE, KM_NOFS);
95#endif
96#ifdef XFS_BMAP_TRACE
97 ip->i_xtrace = ktrace_alloc(XFS_BMAP_KTRACE_SIZE, KM_NOFS);
98#endif
99#ifdef XFS_BTREE_TRACE
100 ip->i_btrace = ktrace_alloc(XFS_BMBT_KTRACE_SIZE, KM_NOFS);
101#endif
102#ifdef XFS_RW_TRACE
103 ip->i_rwtrace = ktrace_alloc(XFS_RW_KTRACE_SIZE, KM_NOFS);
104#endif
105#ifdef XFS_ILOCK_TRACE
106 ip->i_lock_trace = ktrace_alloc(XFS_ILOCK_KTRACE_SIZE, KM_NOFS);
107#endif
108#ifdef XFS_DIR2_TRACE
109 ip->i_dir_trace = ktrace_alloc(XFS_DIR2_KTRACE_SIZE, KM_NOFS);
110#endif
111
112 /* prevent anyone from using this yet */ 93 /* prevent anyone from using this yet */
113 VFS_I(ip)->i_state = I_NEW|I_LOCK; 94 VFS_I(ip)->i_state = I_NEW;
114 95
115 return ip; 96 return ip;
116} 97}
@@ -130,25 +111,6 @@ xfs_inode_free(
130 if (ip->i_afp) 111 if (ip->i_afp)
131 xfs_idestroy_fork(ip, XFS_ATTR_FORK); 112 xfs_idestroy_fork(ip, XFS_ATTR_FORK);
132 113
133#ifdef XFS_INODE_TRACE
134 ktrace_free(ip->i_trace);
135#endif
136#ifdef XFS_BMAP_TRACE
137 ktrace_free(ip->i_xtrace);
138#endif
139#ifdef XFS_BTREE_TRACE
140 ktrace_free(ip->i_btrace);
141#endif
142#ifdef XFS_RW_TRACE
143 ktrace_free(ip->i_rwtrace);
144#endif
145#ifdef XFS_ILOCK_TRACE
146 ktrace_free(ip->i_lock_trace);
147#endif
148#ifdef XFS_DIR2_TRACE
149 ktrace_free(ip->i_dir_trace);
150#endif
151
152 if (ip->i_itemp) { 114 if (ip->i_itemp) {
153 /* 115 /*
154 * Only if we are shutting down the fs will we see an 116 * Only if we are shutting down the fs will we see an
@@ -207,6 +169,7 @@ xfs_iget_cache_hit(
207 * instead of polling for it. 169 * instead of polling for it.
208 */ 170 */
209 if (ip->i_flags & (XFS_INEW|XFS_IRECLAIM)) { 171 if (ip->i_flags & (XFS_INEW|XFS_IRECLAIM)) {
172 trace_xfs_iget_skip(ip);
210 XFS_STATS_INC(xs_ig_frecycle); 173 XFS_STATS_INC(xs_ig_frecycle);
211 error = EAGAIN; 174 error = EAGAIN;
212 goto out_error; 175 goto out_error;
@@ -225,7 +188,7 @@ xfs_iget_cache_hit(
225 * Need to carefully get it back into useable state. 188 * Need to carefully get it back into useable state.
226 */ 189 */
227 if (ip->i_flags & XFS_IRECLAIMABLE) { 190 if (ip->i_flags & XFS_IRECLAIMABLE) {
228 xfs_itrace_exit_tag(ip, "xfs_iget.alloc"); 191 trace_xfs_iget_reclaim(ip);
229 192
230 /* 193 /*
231 * We need to set XFS_INEW atomically with clearing the 194 * We need to set XFS_INEW atomically with clearing the
@@ -251,9 +214,10 @@ xfs_iget_cache_hit(
251 ip->i_flags &= ~XFS_INEW; 214 ip->i_flags &= ~XFS_INEW;
252 ip->i_flags |= XFS_IRECLAIMABLE; 215 ip->i_flags |= XFS_IRECLAIMABLE;
253 __xfs_inode_set_reclaim_tag(pag, ip); 216 __xfs_inode_set_reclaim_tag(pag, ip);
217 trace_xfs_iget_reclaim(ip);
254 goto out_error; 218 goto out_error;
255 } 219 }
256 inode->i_state = I_LOCK|I_NEW; 220 inode->i_state = I_NEW;
257 } else { 221 } else {
258 /* If the VFS inode is being torn down, pause and try again. */ 222 /* If the VFS inode is being torn down, pause and try again. */
259 if (!igrab(inode)) { 223 if (!igrab(inode)) {
@@ -270,8 +234,9 @@ xfs_iget_cache_hit(
270 xfs_ilock(ip, lock_flags); 234 xfs_ilock(ip, lock_flags);
271 235
272 xfs_iflags_clear(ip, XFS_ISTALE); 236 xfs_iflags_clear(ip, XFS_ISTALE);
273 xfs_itrace_exit_tag(ip, "xfs_iget.found");
274 XFS_STATS_INC(xs_ig_found); 237 XFS_STATS_INC(xs_ig_found);
238
239 trace_xfs_iget_found(ip);
275 return 0; 240 return 0;
276 241
277out_error: 242out_error:
@@ -290,7 +255,7 @@ xfs_iget_cache_miss(
290 struct xfs_inode **ipp, 255 struct xfs_inode **ipp,
291 xfs_daddr_t bno, 256 xfs_daddr_t bno,
292 int flags, 257 int flags,
293 int lock_flags) __releases(pag->pag_ici_lock) 258 int lock_flags)
294{ 259{
295 struct xfs_inode *ip; 260 struct xfs_inode *ip;
296 int error; 261 int error;
@@ -305,7 +270,7 @@ xfs_iget_cache_miss(
305 if (error) 270 if (error)
306 goto out_destroy; 271 goto out_destroy;
307 272
308 xfs_itrace_exit_tag(ip, "xfs_iget.alloc"); 273 xfs_itrace_entry(ip);
309 274
310 if ((ip->i_d.di_mode == 0) && !(flags & XFS_IGET_CREATE)) { 275 if ((ip->i_d.di_mode == 0) && !(flags & XFS_IGET_CREATE)) {
311 error = ENOENT; 276 error = ENOENT;
@@ -350,6 +315,8 @@ xfs_iget_cache_miss(
350 315
351 write_unlock(&pag->pag_ici_lock); 316 write_unlock(&pag->pag_ici_lock);
352 radix_tree_preload_end(); 317 radix_tree_preload_end();
318
319 trace_xfs_iget_alloc(ip);
353 *ipp = ip; 320 *ipp = ip;
354 return 0; 321 return 0;
355 322
@@ -511,17 +478,21 @@ xfs_ireclaim(
511{ 478{
512 struct xfs_mount *mp = ip->i_mount; 479 struct xfs_mount *mp = ip->i_mount;
513 struct xfs_perag *pag; 480 struct xfs_perag *pag;
481 xfs_agino_t agino = XFS_INO_TO_AGINO(mp, ip->i_ino);
514 482
515 XFS_STATS_INC(xs_ig_reclaims); 483 XFS_STATS_INC(xs_ig_reclaims);
516 484
517 /* 485 /*
518 * Remove the inode from the per-AG radix tree. It doesn't matter 486 * Remove the inode from the per-AG radix tree.
519 * if it was never added to it because radix_tree_delete can deal 487 *
520 * with that case just fine. 488 * Because radix_tree_delete won't complain even if the item was never
489 * added to the tree assert that it's been there before to catch
490 * problems with the inode life time early on.
521 */ 491 */
522 pag = xfs_get_perag(mp, ip->i_ino); 492 pag = xfs_get_perag(mp, ip->i_ino);
523 write_lock(&pag->pag_ici_lock); 493 write_lock(&pag->pag_ici_lock);
524 radix_tree_delete(&pag->pag_ici_root, XFS_INO_TO_AGINO(mp, ip->i_ino)); 494 if (!radix_tree_delete(&pag->pag_ici_root, agino))
495 ASSERT(0);
525 write_unlock(&pag->pag_ici_lock); 496 write_unlock(&pag->pag_ici_lock);
526 xfs_put_perag(mp, pag); 497 xfs_put_perag(mp, pag);
527 498
@@ -636,7 +607,7 @@ xfs_ilock(
636 else if (lock_flags & XFS_ILOCK_SHARED) 607 else if (lock_flags & XFS_ILOCK_SHARED)
637 mraccess_nested(&ip->i_lock, XFS_ILOCK_DEP(lock_flags)); 608 mraccess_nested(&ip->i_lock, XFS_ILOCK_DEP(lock_flags));
638 609
639 xfs_ilock_trace(ip, 1, lock_flags, (inst_t *)__return_address); 610 trace_xfs_ilock(ip, lock_flags, _RET_IP_);
640} 611}
641 612
642/* 613/*
@@ -681,7 +652,7 @@ xfs_ilock_nowait(
681 if (!mrtryaccess(&ip->i_lock)) 652 if (!mrtryaccess(&ip->i_lock))
682 goto out_undo_iolock; 653 goto out_undo_iolock;
683 } 654 }
684 xfs_ilock_trace(ip, 2, lock_flags, (inst_t *)__return_address); 655 trace_xfs_ilock_nowait(ip, lock_flags, _RET_IP_);
685 return 1; 656 return 1;
686 657
687 out_undo_iolock: 658 out_undo_iolock:
@@ -743,7 +714,7 @@ xfs_iunlock(
743 xfs_trans_unlocked_item(ip->i_itemp->ili_item.li_ailp, 714 xfs_trans_unlocked_item(ip->i_itemp->ili_item.li_ailp,
744 (xfs_log_item_t*)(ip->i_itemp)); 715 (xfs_log_item_t*)(ip->i_itemp));
745 } 716 }
746 xfs_ilock_trace(ip, 3, lock_flags, (inst_t *)__return_address); 717 trace_xfs_iunlock(ip, lock_flags, _RET_IP_);
747} 718}
748 719
749/* 720/*
@@ -762,6 +733,8 @@ xfs_ilock_demote(
762 mrdemote(&ip->i_lock); 733 mrdemote(&ip->i_lock);
763 if (lock_flags & XFS_IOLOCK_EXCL) 734 if (lock_flags & XFS_IOLOCK_EXCL)
764 mrdemote(&ip->i_iolock); 735 mrdemote(&ip->i_iolock);
736
737 trace_xfs_ilock_demote(ip, lock_flags, _RET_IP_);
765} 738}
766 739
767#ifdef DEBUG 740#ifdef DEBUG
@@ -792,52 +765,3 @@ xfs_isilocked(
792 return 1; 765 return 1;
793} 766}
794#endif 767#endif
795
796#ifdef XFS_INODE_TRACE
797
798#define KTRACE_ENTER(ip, vk, s, line, ra) \
799 ktrace_enter((ip)->i_trace, \
800/* 0 */ (void *)(__psint_t)(vk), \
801/* 1 */ (void *)(s), \
802/* 2 */ (void *)(__psint_t) line, \
803/* 3 */ (void *)(__psint_t)atomic_read(&VFS_I(ip)->i_count), \
804/* 4 */ (void *)(ra), \
805/* 5 */ NULL, \
806/* 6 */ (void *)(__psint_t)current_cpu(), \
807/* 7 */ (void *)(__psint_t)current_pid(), \
808/* 8 */ (void *)__return_address, \
809/* 9 */ NULL, NULL, NULL, NULL, NULL, NULL, NULL)
810
811/*
812 * Vnode tracing code.
813 */
814void
815_xfs_itrace_entry(xfs_inode_t *ip, const char *func, inst_t *ra)
816{
817 KTRACE_ENTER(ip, INODE_KTRACE_ENTRY, func, 0, ra);
818}
819
820void
821_xfs_itrace_exit(xfs_inode_t *ip, const char *func, inst_t *ra)
822{
823 KTRACE_ENTER(ip, INODE_KTRACE_EXIT, func, 0, ra);
824}
825
826void
827xfs_itrace_hold(xfs_inode_t *ip, char *file, int line, inst_t *ra)
828{
829 KTRACE_ENTER(ip, INODE_KTRACE_HOLD, file, line, ra);
830}
831
832void
833_xfs_itrace_ref(xfs_inode_t *ip, char *file, int line, inst_t *ra)
834{
835 KTRACE_ENTER(ip, INODE_KTRACE_REF, file, line, ra);
836}
837
838void
839xfs_itrace_rele(xfs_inode_t *ip, char *file, int line, inst_t *ra)
840{
841 KTRACE_ENTER(ip, INODE_KTRACE_RELE, file, line, ra);
842}
843#endif /* XFS_INODE_TRACE */