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.c142
1 files changed, 65 insertions, 77 deletions
diff --git a/fs/xfs/xfs_iget.c b/fs/xfs/xfs_iget.c
index 15dba2ef847..eecc33d3751 100644
--- a/fs/xfs/xfs_iget.c
+++ b/fs/xfs/xfs_iget.c
@@ -65,7 +65,7 @@
65 */ 65 */
66STATIC int 66STATIC int
67xfs_iget_core( 67xfs_iget_core(
68 bhv_vnode_t *vp, 68 struct inode *inode,
69 xfs_mount_t *mp, 69 xfs_mount_t *mp,
70 xfs_trans_t *tp, 70 xfs_trans_t *tp,
71 xfs_ino_t ino, 71 xfs_ino_t ino,
@@ -74,9 +74,9 @@ xfs_iget_core(
74 xfs_inode_t **ipp, 74 xfs_inode_t **ipp,
75 xfs_daddr_t bno) 75 xfs_daddr_t bno)
76{ 76{
77 struct inode *old_inode;
77 xfs_inode_t *ip; 78 xfs_inode_t *ip;
78 xfs_inode_t *iq; 79 xfs_inode_t *iq;
79 bhv_vnode_t *inode_vp;
80 int error; 80 int error;
81 xfs_icluster_t *icl, *new_icl = NULL; 81 xfs_icluster_t *icl, *new_icl = NULL;
82 unsigned long first_index, mask; 82 unsigned long first_index, mask;
@@ -111,8 +111,8 @@ again:
111 goto again; 111 goto again;
112 } 112 }
113 113
114 inode_vp = XFS_ITOV_NULL(ip); 114 old_inode = ip->i_vnode;
115 if (inode_vp == NULL) { 115 if (old_inode == NULL) {
116 /* 116 /*
117 * If IRECLAIM is set this inode is 117 * If IRECLAIM is set this inode is
118 * on its way out of the system, 118 * on its way out of the system,
@@ -170,13 +170,11 @@ again:
170 170
171 goto finish_inode; 171 goto finish_inode;
172 172
173 } else if (vp != inode_vp) { 173 } else if (inode != old_inode) {
174 struct inode *inode = vn_to_inode(inode_vp);
175
176 /* The inode is being torn down, pause and 174 /* The inode is being torn down, pause and
177 * try again. 175 * try again.
178 */ 176 */
179 if (inode->i_state & (I_FREEING | I_CLEAR)) { 177 if (old_inode->i_state & (I_FREEING | I_CLEAR)) {
180 read_unlock(&pag->pag_ici_lock); 178 read_unlock(&pag->pag_ici_lock);
181 delay(1); 179 delay(1);
182 XFS_STATS_INC(xs_ig_frecycle); 180 XFS_STATS_INC(xs_ig_frecycle);
@@ -189,7 +187,7 @@ again:
189*/ 187*/
190 cmn_err(CE_PANIC, 188 cmn_err(CE_PANIC,
191 "xfs_iget_core: ambiguous vns: vp/0x%p, invp/0x%p", 189 "xfs_iget_core: ambiguous vns: vp/0x%p, invp/0x%p",
192 inode_vp, vp); 190 old_inode, inode);
193 } 191 }
194 192
195 /* 193 /*
@@ -231,7 +229,14 @@ finish_inode:
231 229
232 xfs_itrace_exit_tag(ip, "xfs_iget.alloc"); 230 xfs_itrace_exit_tag(ip, "xfs_iget.alloc");
233 231
234 xfs_inode_lock_init(ip, vp); 232
233 mrlock_init(&ip->i_lock, MRLOCK_ALLOW_EQUAL_PRI|MRLOCK_BARRIER,
234 "xfsino", ip->i_ino);
235 mrlock_init(&ip->i_iolock, MRLOCK_BARRIER, "xfsio", ip->i_ino);
236 init_waitqueue_head(&ip->i_ipin_wait);
237 atomic_set(&ip->i_pincount, 0);
238 initnsema(&ip->i_flock, 1, "xfsfino");
239
235 if (lock_flags) 240 if (lock_flags)
236 xfs_ilock(ip, lock_flags); 241 xfs_ilock(ip, lock_flags);
237 242
@@ -334,7 +339,7 @@ finish_inode:
334 * If we have a real type for an on-disk inode, we can set ops(&unlock) 339 * If we have a real type for an on-disk inode, we can set ops(&unlock)
335 * now. If it's a new inode being created, xfs_ialloc will handle it. 340 * now. If it's a new inode being created, xfs_ialloc will handle it.
336 */ 341 */
337 xfs_initialize_vnode(mp, vp, ip); 342 xfs_initialize_vnode(mp, inode, ip);
338 return 0; 343 return 0;
339} 344}
340 345
@@ -354,69 +359,58 @@ xfs_iget(
354 xfs_daddr_t bno) 359 xfs_daddr_t bno)
355{ 360{
356 struct inode *inode; 361 struct inode *inode;
357 bhv_vnode_t *vp = NULL; 362 xfs_inode_t *ip;
358 int error; 363 int error;
359 364
360 XFS_STATS_INC(xs_ig_attempts); 365 XFS_STATS_INC(xs_ig_attempts);
361 366
362retry: 367retry:
363 inode = iget_locked(mp->m_super, ino); 368 inode = iget_locked(mp->m_super, ino);
364 if (inode) { 369 if (!inode)
365 xfs_inode_t *ip; 370 /* If we got no inode we are out of memory */
366 371 return ENOMEM;
367 vp = vn_from_inode(inode); 372
368 if (inode->i_state & I_NEW) { 373 if (inode->i_state & I_NEW) {
369 vn_initialize(inode); 374 XFS_STATS_INC(vn_active);
370 error = xfs_iget_core(vp, mp, tp, ino, flags, 375 XFS_STATS_INC(vn_alloc);
371 lock_flags, ipp, bno); 376
372 if (error) { 377 error = xfs_iget_core(inode, mp, tp, ino, flags,
373 vn_mark_bad(vp); 378 lock_flags, ipp, bno);
374 if (inode->i_state & I_NEW) 379 if (error) {
375 unlock_new_inode(inode); 380 make_bad_inode(inode);
376 iput(inode); 381 if (inode->i_state & I_NEW)
377 } 382 unlock_new_inode(inode);
378 } else { 383 iput(inode);
379 /*
380 * If the inode is not fully constructed due to
381 * filehandle mismatches wait for the inode to go
382 * away and try again.
383 *
384 * iget_locked will call __wait_on_freeing_inode
385 * to wait for the inode to go away.
386 */
387 if (is_bad_inode(inode) ||
388 ((ip = xfs_vtoi(vp)) == NULL)) {
389 iput(inode);
390 delay(1);
391 goto retry;
392 }
393
394 if (lock_flags != 0)
395 xfs_ilock(ip, lock_flags);
396 XFS_STATS_INC(xs_ig_found);
397 *ipp = ip;
398 error = 0;
399 } 384 }
400 } else 385 return error;
401 error = ENOMEM; /* If we got no inode we are out of memory */ 386 }
402 387
403 return error; 388 /*
404} 389 * If the inode is not fully constructed due to
390 * filehandle mismatches wait for the inode to go
391 * away and try again.
392 *
393 * iget_locked will call __wait_on_freeing_inode
394 * to wait for the inode to go away.
395 */
396 if (is_bad_inode(inode)) {
397 iput(inode);
398 delay(1);
399 goto retry;
400 }
405 401
406/* 402 ip = XFS_I(inode);
407 * Do the setup for the various locks within the incore inode. 403 if (!ip) {
408 */ 404 iput(inode);
409void 405 delay(1);
410xfs_inode_lock_init( 406 goto retry;
411 xfs_inode_t *ip, 407 }
412 bhv_vnode_t *vp) 408
413{ 409 if (lock_flags != 0)
414 mrlock_init(&ip->i_lock, MRLOCK_ALLOW_EQUAL_PRI|MRLOCK_BARRIER, 410 xfs_ilock(ip, lock_flags);
415 "xfsino", ip->i_ino); 411 XFS_STATS_INC(xs_ig_found);
416 mrlock_init(&ip->i_iolock, MRLOCK_BARRIER, "xfsio", ip->i_ino); 412 *ipp = ip;
417 init_waitqueue_head(&ip->i_ipin_wait); 413 return 0;
418 atomic_set(&ip->i_pincount, 0);
419 initnsema(&ip->i_flock, 1, "xfsfino");
420} 414}
421 415
422/* 416/*
@@ -456,11 +450,9 @@ void
456xfs_iput(xfs_inode_t *ip, 450xfs_iput(xfs_inode_t *ip,
457 uint lock_flags) 451 uint lock_flags)
458{ 452{
459 bhv_vnode_t *vp = XFS_ITOV(ip);
460
461 xfs_itrace_entry(ip); 453 xfs_itrace_entry(ip);
462 xfs_iunlock(ip, lock_flags); 454 xfs_iunlock(ip, lock_flags);
463 VN_RELE(vp); 455 IRELE(ip);
464} 456}
465 457
466/* 458/*
@@ -470,20 +462,19 @@ void
470xfs_iput_new(xfs_inode_t *ip, 462xfs_iput_new(xfs_inode_t *ip,
471 uint lock_flags) 463 uint lock_flags)
472{ 464{
473 bhv_vnode_t *vp = XFS_ITOV(ip); 465 struct inode *inode = ip->i_vnode;
474 struct inode *inode = vn_to_inode(vp);
475 466
476 xfs_itrace_entry(ip); 467 xfs_itrace_entry(ip);
477 468
478 if ((ip->i_d.di_mode == 0)) { 469 if ((ip->i_d.di_mode == 0)) {
479 ASSERT(!xfs_iflags_test(ip, XFS_IRECLAIMABLE)); 470 ASSERT(!xfs_iflags_test(ip, XFS_IRECLAIMABLE));
480 vn_mark_bad(vp); 471 make_bad_inode(inode);
481 } 472 }
482 if (inode->i_state & I_NEW) 473 if (inode->i_state & I_NEW)
483 unlock_new_inode(inode); 474 unlock_new_inode(inode);
484 if (lock_flags) 475 if (lock_flags)
485 xfs_iunlock(ip, lock_flags); 476 xfs_iunlock(ip, lock_flags);
486 VN_RELE(vp); 477 IRELE(ip);
487} 478}
488 479
489 480
@@ -496,8 +487,6 @@ xfs_iput_new(xfs_inode_t *ip,
496void 487void
497xfs_ireclaim(xfs_inode_t *ip) 488xfs_ireclaim(xfs_inode_t *ip)
498{ 489{
499 bhv_vnode_t *vp;
500
501 /* 490 /*
502 * Remove from old hash list and mount list. 491 * Remove from old hash list and mount list.
503 */ 492 */
@@ -526,9 +515,8 @@ xfs_ireclaim(xfs_inode_t *ip)
526 /* 515 /*
527 * Pull our behavior descriptor from the vnode chain. 516 * Pull our behavior descriptor from the vnode chain.
528 */ 517 */
529 vp = XFS_ITOV_NULL(ip); 518 if (ip->i_vnode) {
530 if (vp) { 519 ip->i_vnode->i_private = NULL;
531 vn_to_inode(vp)->i_private = NULL;
532 ip->i_vnode = NULL; 520 ip->i_vnode = NULL;
533 } 521 }
534 522