diff options
Diffstat (limited to 'fs/xfs/xfs_iget.c')
-rw-r--r-- | fs/xfs/xfs_iget.c | 132 |
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 | ||
277 | out_error: | 242 | out_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 | */ | ||
814 | void | ||
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 | |||
820 | void | ||
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 | |||
826 | void | ||
827 | xfs_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 | |||
832 | void | ||
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 | |||
838 | void | ||
839 | xfs_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 */ | ||