aboutsummaryrefslogtreecommitdiffstats
path: root/fs/xfs/xfs_iget.c
diff options
context:
space:
mode:
authorAndrea Bastoni <bastoni@cs.unc.edu>2010-05-30 19:16:45 -0400
committerAndrea Bastoni <bastoni@cs.unc.edu>2010-05-30 19:16:45 -0400
commitada47b5fe13d89735805b566185f4885f5a3f750 (patch)
tree644b88f8a71896307d71438e9b3af49126ffb22b /fs/xfs/xfs_iget.c
parent43e98717ad40a4ae64545b5ba047c7b86aa44f4f (diff)
parent3280f21d43ee541f97f8cda5792150d2dbec20d5 (diff)
Merge branch 'wip-2.6.34' into old-private-masterarchived-private-master
Diffstat (limited to 'fs/xfs/xfs_iget.c')
-rw-r--r--fs/xfs/xfs_iget.c160
1 files changed, 45 insertions, 115 deletions
diff --git a/fs/xfs/xfs_iget.c b/fs/xfs/xfs_iget.c
index 80e526489be5..6845db90818f 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/*
@@ -74,6 +74,8 @@ xfs_inode_alloc(
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 76
77 mrlock_init(&ip->i_iolock, MRLOCK_BARRIER, "xfsio", ip->i_ino);
78
77 /* initialise the xfs inode */ 79 /* initialise the xfs inode */
78 ip->i_ino = ino; 80 ip->i_ino = ino;
79 ip->i_mount = mp; 81 ip->i_mount = mp;
@@ -87,30 +89,8 @@ xfs_inode_alloc(
87 ip->i_size = 0; 89 ip->i_size = 0;
88 ip->i_new_size = 0; 90 ip->i_new_size = 0;
89 91
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 */ 92 /* prevent anyone from using this yet */
113 VFS_I(ip)->i_state = I_NEW|I_LOCK; 93 VFS_I(ip)->i_state = I_NEW;
114 94
115 return ip; 95 return ip;
116} 96}
@@ -130,25 +110,6 @@ xfs_inode_free(
130 if (ip->i_afp) 110 if (ip->i_afp)
131 xfs_idestroy_fork(ip, XFS_ATTR_FORK); 111 xfs_idestroy_fork(ip, XFS_ATTR_FORK);
132 112
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) { 113 if (ip->i_itemp) {
153 /* 114 /*
154 * Only if we are shutting down the fs will we see an 115 * Only if we are shutting down the fs will we see an
@@ -207,6 +168,7 @@ xfs_iget_cache_hit(
207 * instead of polling for it. 168 * instead of polling for it.
208 */ 169 */
209 if (ip->i_flags & (XFS_INEW|XFS_IRECLAIM)) { 170 if (ip->i_flags & (XFS_INEW|XFS_IRECLAIM)) {
171 trace_xfs_iget_skip(ip);
210 XFS_STATS_INC(xs_ig_frecycle); 172 XFS_STATS_INC(xs_ig_frecycle);
211 error = EAGAIN; 173 error = EAGAIN;
212 goto out_error; 174 goto out_error;
@@ -225,16 +187,15 @@ xfs_iget_cache_hit(
225 * Need to carefully get it back into useable state. 187 * Need to carefully get it back into useable state.
226 */ 188 */
227 if (ip->i_flags & XFS_IRECLAIMABLE) { 189 if (ip->i_flags & XFS_IRECLAIMABLE) {
228 xfs_itrace_exit_tag(ip, "xfs_iget.alloc"); 190 trace_xfs_iget_reclaim(ip);
229 191
230 /* 192 /*
231 * We need to set XFS_INEW atomically with clearing the 193 * We need to set XFS_IRECLAIM to prevent xfs_reclaim_inode
232 * reclaimable tag so that we do have an indicator of the 194 * from stomping over us while we recycle the inode. We can't
233 * inode still being initialized. 195 * clear the radix tree reclaimable tag yet as it requires
196 * pag_ici_lock to be held exclusive.
234 */ 197 */
235 ip->i_flags |= XFS_INEW; 198 ip->i_flags |= XFS_IRECLAIM;
236 ip->i_flags &= ~XFS_IRECLAIMABLE;
237 __xfs_inode_clear_reclaim_tag(mp, pag, ip);
238 199
239 spin_unlock(&ip->i_flags_lock); 200 spin_unlock(&ip->i_flags_lock);
240 read_unlock(&pag->pag_ici_lock); 201 read_unlock(&pag->pag_ici_lock);
@@ -251,9 +212,18 @@ xfs_iget_cache_hit(
251 ip->i_flags &= ~XFS_INEW; 212 ip->i_flags &= ~XFS_INEW;
252 ip->i_flags |= XFS_IRECLAIMABLE; 213 ip->i_flags |= XFS_IRECLAIMABLE;
253 __xfs_inode_set_reclaim_tag(pag, ip); 214 __xfs_inode_set_reclaim_tag(pag, ip);
215 trace_xfs_iget_reclaim(ip);
254 goto out_error; 216 goto out_error;
255 } 217 }
256 inode->i_state = I_LOCK|I_NEW; 218
219 write_lock(&pag->pag_ici_lock);
220 spin_lock(&ip->i_flags_lock);
221 ip->i_flags &= ~(XFS_IRECLAIMABLE | XFS_IRECLAIM);
222 ip->i_flags |= XFS_INEW;
223 __xfs_inode_clear_reclaim_tag(mp, pag, ip);
224 inode->i_state = I_NEW;
225 spin_unlock(&ip->i_flags_lock);
226 write_unlock(&pag->pag_ici_lock);
257 } else { 227 } else {
258 /* If the VFS inode is being torn down, pause and try again. */ 228 /* If the VFS inode is being torn down, pause and try again. */
259 if (!igrab(inode)) { 229 if (!igrab(inode)) {
@@ -270,8 +240,9 @@ xfs_iget_cache_hit(
270 xfs_ilock(ip, lock_flags); 240 xfs_ilock(ip, lock_flags);
271 241
272 xfs_iflags_clear(ip, XFS_ISTALE); 242 xfs_iflags_clear(ip, XFS_ISTALE);
273 xfs_itrace_exit_tag(ip, "xfs_iget.found");
274 XFS_STATS_INC(xs_ig_found); 243 XFS_STATS_INC(xs_ig_found);
244
245 trace_xfs_iget_found(ip);
275 return 0; 246 return 0;
276 247
277out_error: 248out_error:
@@ -290,7 +261,7 @@ xfs_iget_cache_miss(
290 struct xfs_inode **ipp, 261 struct xfs_inode **ipp,
291 xfs_daddr_t bno, 262 xfs_daddr_t bno,
292 int flags, 263 int flags,
293 int lock_flags) __releases(pag->pag_ici_lock) 264 int lock_flags)
294{ 265{
295 struct xfs_inode *ip; 266 struct xfs_inode *ip;
296 int error; 267 int error;
@@ -305,7 +276,7 @@ xfs_iget_cache_miss(
305 if (error) 276 if (error)
306 goto out_destroy; 277 goto out_destroy;
307 278
308 xfs_itrace_exit_tag(ip, "xfs_iget.alloc"); 279 xfs_itrace_entry(ip);
309 280
310 if ((ip->i_d.di_mode == 0) && !(flags & XFS_IGET_CREATE)) { 281 if ((ip->i_d.di_mode == 0) && !(flags & XFS_IGET_CREATE)) {
311 error = ENOENT; 282 error = ENOENT;
@@ -350,6 +321,8 @@ xfs_iget_cache_miss(
350 321
351 write_unlock(&pag->pag_ici_lock); 322 write_unlock(&pag->pag_ici_lock);
352 radix_tree_preload_end(); 323 radix_tree_preload_end();
324
325 trace_xfs_iget_alloc(ip);
353 *ipp = ip; 326 *ipp = ip;
354 return 0; 327 return 0;
355 328
@@ -408,7 +381,7 @@ xfs_iget(
408 return EINVAL; 381 return EINVAL;
409 382
410 /* get the perag structure and ensure that it's inode capable */ 383 /* get the perag structure and ensure that it's inode capable */
411 pag = xfs_get_perag(mp, ino); 384 pag = xfs_perag_get(mp, XFS_INO_TO_AGNO(mp, ino));
412 if (!pag->pagi_inodeok) 385 if (!pag->pagi_inodeok)
413 return EINVAL; 386 return EINVAL;
414 ASSERT(pag->pag_ici_init); 387 ASSERT(pag->pag_ici_init);
@@ -432,7 +405,7 @@ again:
432 if (error) 405 if (error)
433 goto out_error_or_again; 406 goto out_error_or_again;
434 } 407 }
435 xfs_put_perag(mp, pag); 408 xfs_perag_put(pag);
436 409
437 *ipp = ip; 410 *ipp = ip;
438 411
@@ -451,7 +424,7 @@ out_error_or_again:
451 delay(1); 424 delay(1);
452 goto again; 425 goto again;
453 } 426 }
454 xfs_put_perag(mp, pag); 427 xfs_perag_put(pag);
455 return error; 428 return error;
456} 429}
457 430
@@ -511,19 +484,23 @@ xfs_ireclaim(
511{ 484{
512 struct xfs_mount *mp = ip->i_mount; 485 struct xfs_mount *mp = ip->i_mount;
513 struct xfs_perag *pag; 486 struct xfs_perag *pag;
487 xfs_agino_t agino = XFS_INO_TO_AGINO(mp, ip->i_ino);
514 488
515 XFS_STATS_INC(xs_ig_reclaims); 489 XFS_STATS_INC(xs_ig_reclaims);
516 490
517 /* 491 /*
518 * Remove the inode from the per-AG radix tree. It doesn't matter 492 * Remove the inode from the per-AG radix tree.
519 * if it was never added to it because radix_tree_delete can deal 493 *
520 * with that case just fine. 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.
521 */ 497 */
522 pag = xfs_get_perag(mp, ip->i_ino); 498 pag = xfs_perag_get(mp, XFS_INO_TO_AGNO(mp, ip->i_ino));
523 write_lock(&pag->pag_ici_lock); 499 write_lock(&pag->pag_ici_lock);
524 radix_tree_delete(&pag->pag_ici_root, XFS_INO_TO_AGINO(mp, ip->i_ino)); 500 if (!radix_tree_delete(&pag->pag_ici_root, agino))
501 ASSERT(0);
525 write_unlock(&pag->pag_ici_lock); 502 write_unlock(&pag->pag_ici_lock);
526 xfs_put_perag(mp, pag); 503 xfs_perag_put(pag);
527 504
528 /* 505 /*
529 * Here we do an (almost) spurious inode lock in order to coordinate 506 * Here we do an (almost) spurious inode lock in order to coordinate
@@ -636,7 +613,7 @@ xfs_ilock(
636 else if (lock_flags & XFS_ILOCK_SHARED) 613 else if (lock_flags & XFS_ILOCK_SHARED)
637 mraccess_nested(&ip->i_lock, XFS_ILOCK_DEP(lock_flags)); 614 mraccess_nested(&ip->i_lock, XFS_ILOCK_DEP(lock_flags));
638 615
639 xfs_ilock_trace(ip, 1, lock_flags, (inst_t *)__return_address); 616 trace_xfs_ilock(ip, lock_flags, _RET_IP_);
640} 617}
641 618
642/* 619/*
@@ -681,7 +658,7 @@ xfs_ilock_nowait(
681 if (!mrtryaccess(&ip->i_lock)) 658 if (!mrtryaccess(&ip->i_lock))
682 goto out_undo_iolock; 659 goto out_undo_iolock;
683 } 660 }
684 xfs_ilock_trace(ip, 2, lock_flags, (inst_t *)__return_address); 661 trace_xfs_ilock_nowait(ip, lock_flags, _RET_IP_);
685 return 1; 662 return 1;
686 663
687 out_undo_iolock: 664 out_undo_iolock:
@@ -743,7 +720,7 @@ xfs_iunlock(
743 xfs_trans_unlocked_item(ip->i_itemp->ili_item.li_ailp, 720 xfs_trans_unlocked_item(ip->i_itemp->ili_item.li_ailp,
744 (xfs_log_item_t*)(ip->i_itemp)); 721 (xfs_log_item_t*)(ip->i_itemp));
745 } 722 }
746 xfs_ilock_trace(ip, 3, lock_flags, (inst_t *)__return_address); 723 trace_xfs_iunlock(ip, lock_flags, _RET_IP_);
747} 724}
748 725
749/* 726/*
@@ -762,6 +739,8 @@ xfs_ilock_demote(
762 mrdemote(&ip->i_lock); 739 mrdemote(&ip->i_lock);
763 if (lock_flags & XFS_IOLOCK_EXCL) 740 if (lock_flags & XFS_IOLOCK_EXCL)
764 mrdemote(&ip->i_iolock); 741 mrdemote(&ip->i_iolock);
742
743 trace_xfs_ilock_demote(ip, lock_flags, _RET_IP_);
765} 744}
766 745
767#ifdef DEBUG 746#ifdef DEBUG
@@ -792,52 +771,3 @@ xfs_isilocked(
792 return 1; 771 return 1;
793} 772}
794#endif 773#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 */