|
|
| version 1.235, 2007/09/21 16:10:12 | version 1.236, 2007/10/01 15:55:30 |
|---|---|
| Line 65 | Line 65 |
| */ | */ |
| STATIC int | STATIC int |
| xfs_iget_core( | xfs_iget_core( |
| bhv_vnode_t *vp, | struct inode *inode, |
| xfs_mount_t *mp, | xfs_mount_t *mp, |
| xfs_trans_t *tp, | xfs_trans_t *tp, |
| xfs_ino_t ino, | xfs_ino_t ino, |
| Line 74 xfs_iget_core( | Line 74 xfs_iget_core( |
| xfs_inode_t **ipp, | xfs_inode_t **ipp, |
| xfs_daddr_t bno) | xfs_daddr_t bno) |
| { | { |
| struct inode *old_inode; | |
| xfs_inode_t *ip; | xfs_inode_t *ip; |
| xfs_inode_t *iq; | xfs_inode_t *iq; |
| bhv_vnode_t *inode_vp; | |
| int error; | int error; |
| xfs_icluster_t *icl, *new_icl = NULL; | xfs_icluster_t *icl, *new_icl = NULL; |
| unsigned long first_index, mask; | unsigned long first_index, mask; |
| Line 111 again: | Line 111 again: |
| goto again; | goto again; |
| } | } |
| inode_vp = XFS_ITOV_NULL(ip); | old_inode = ip->i_vnode; |
| if (inode_vp == NULL) { | if (old_inode == NULL) { |
| /* | /* |
| * If IRECLAIM is set this inode is | * If IRECLAIM is set this inode is |
| * on its way out of the system, | * on its way out of the system, |
| Line 170 again: | Line 170 again: |
| goto finish_inode; | goto finish_inode; |
| } else if (vp != inode_vp) { | } else if (inode != old_inode) { |
| struct inode *inode = vn_to_inode(inode_vp); | |
| /* The inode is being torn down, pause and | /* The inode is being torn down, pause and |
| * try again. | * try again. |
| */ | */ |
| if (inode->i_state & (I_FREEING | I_CLEAR)) { | if (old_inode->i_state & (I_FREEING | I_CLEAR)) { |
| read_unlock(&pag->pag_ici_lock); | read_unlock(&pag->pag_ici_lock); |
| delay(1); | delay(1); |
| XFS_STATS_INC(xs_ig_frecycle); | XFS_STATS_INC(xs_ig_frecycle); |
| Line 189 again: | Line 187 again: |
| */ | */ |
| cmn_err(CE_PANIC, | cmn_err(CE_PANIC, |
| "xfs_iget_core: ambiguous vns: vp/0x%p, invp/0x%p", | "xfs_iget_core: ambiguous vns: vp/0x%p, invp/0x%p", |
| inode_vp, vp); | old_inode, inode); |
| } | } |
| /* | /* |
| Line 231 finish_inode: | Line 229 finish_inode: |
| xfs_itrace_exit_tag(ip, "xfs_iget.alloc"); | xfs_itrace_exit_tag(ip, "xfs_iget.alloc"); |
| xfs_inode_lock_init(ip, vp); | |
| mrlock_init(&ip->i_lock, MRLOCK_ALLOW_EQUAL_PRI|MRLOCK_BARRIER, | |
| "xfsino", ip->i_ino); | |
| mrlock_init(&ip->i_iolock, MRLOCK_BARRIER, "xfsio", ip->i_ino); | |
| init_waitqueue_head(&ip->i_ipin_wait); | |
| atomic_set(&ip->i_pincount, 0); | |
| initnsema(&ip->i_flock, 1, "xfsfino"); | |
| if (lock_flags) | if (lock_flags) |
| xfs_ilock(ip, lock_flags); | xfs_ilock(ip, lock_flags); |
| Line 334 finish_inode: | Line 339 finish_inode: |
| * If we have a real type for an on-disk inode, we can set ops(&unlock) | * If we have a real type for an on-disk inode, we can set ops(&unlock) |
| * now. If it's a new inode being created, xfs_ialloc will handle it. | * now. If it's a new inode being created, xfs_ialloc will handle it. |
| */ | */ |
| xfs_initialize_vnode(mp, vp, ip); | xfs_initialize_vnode(mp, inode, ip); |
| return 0; | return 0; |
| } | } |
| Line 354 xfs_iget( | Line 359 xfs_iget( |
| xfs_daddr_t bno) | xfs_daddr_t bno) |
| { | { |
| struct inode *inode; | struct inode *inode; |
| bhv_vnode_t *vp = NULL; | xfs_inode_t *ip; |
| int error; | int error; |
| XFS_STATS_INC(xs_ig_attempts); | XFS_STATS_INC(xs_ig_attempts); |
| retry: | retry: |
| inode = iget_locked(mp->m_super, ino); | inode = iget_locked(mp->m_super, ino); |
| if (inode) { | if (!inode) |
| xfs_inode_t *ip; | /* If we got no inode we are out of memory */ |
| return ENOMEM; | |
| vp = vn_from_inode(inode); | |
| if (inode->i_state & I_NEW) { | if (inode->i_state & I_NEW) { |
| vn_initialize(inode); | XFS_STATS_INC(vn_active); |
| error = xfs_iget_core(vp, mp, tp, ino, flags, | XFS_STATS_INC(vn_alloc); |
| lock_flags, ipp, bno); | |
| if (error) { | error = xfs_iget_core(inode, mp, tp, ino, flags, |
| vn_mark_bad(vp); | lock_flags, ipp, bno); |
| if (inode->i_state & I_NEW) | if (error) { |
| unlock_new_inode(inode); | make_bad_inode(inode); |
| iput(inode); | if (inode->i_state & I_NEW) |
| } | unlock_new_inode(inode); |
| } else { | iput(inode); |
| /* | |
| * If the inode is not fully constructed due to | |
| * filehandle mismatches wait for the inode to go | |
| * away and try again. | |
| * | |
| * iget_locked will call __wait_on_freeing_inode | |
| * to wait for the inode to go away. | |
| */ | |
| if (is_bad_inode(inode) || | |
| ((ip = xfs_vtoi(vp)) == NULL)) { | |
| iput(inode); | |
| delay(1); | |
| goto retry; | |
| } | |
| if (lock_flags != 0) | |
| xfs_ilock(ip, lock_flags); | |
| XFS_STATS_INC(xs_ig_found); | |
| *ipp = ip; | |
| error = 0; | |
| } | } |
| } else | return error; |
| error = ENOMEM; /* If we got no inode we are out of memory */ | } |
| return error; | /* |
| } | * If the inode is not fully constructed due to |
| * filehandle mismatches wait for the inode to go | |
| * away and try again. | |
| * | |
| * iget_locked will call __wait_on_freeing_inode | |
| * to wait for the inode to go away. | |
| */ | |
| if (is_bad_inode(inode)) { | |
| iput(inode); | |
| delay(1); | |
| goto retry; | |
| } | |
| /* | ip = XFS_I(inode); |
| * Do the setup for the various locks within the incore inode. | if (!ip) { |
| */ | iput(inode); |
| void | delay(1); |
| xfs_inode_lock_init( | goto retry; |
| xfs_inode_t *ip, | } |
| bhv_vnode_t *vp) | |
| { | if (lock_flags != 0) |
| mrlock_init(&ip->i_lock, MRLOCK_ALLOW_EQUAL_PRI|MRLOCK_BARRIER, | xfs_ilock(ip, lock_flags); |
| "xfsino", ip->i_ino); | XFS_STATS_INC(xs_ig_found); |
| mrlock_init(&ip->i_iolock, MRLOCK_BARRIER, "xfsio", ip->i_ino); | *ipp = ip; |
| init_waitqueue_head(&ip->i_ipin_wait); | return 0; |
| atomic_set(&ip->i_pincount, 0); | |
| initnsema(&ip->i_flock, 1, "xfsfino"); | |
| } | } |
| /* | /* |
| Line 456 void | Line 450 void |
| xfs_iput(xfs_inode_t *ip, | xfs_iput(xfs_inode_t *ip, |
| uint lock_flags) | uint lock_flags) |
| { | { |
| bhv_vnode_t *vp = XFS_ITOV(ip); | |
| xfs_itrace_entry(ip); | xfs_itrace_entry(ip); |
| xfs_iunlock(ip, lock_flags); | xfs_iunlock(ip, lock_flags); |
| VN_RELE(vp); | IRELE(ip); |
| } | } |
| /* | /* |
| Line 470 void | Line 462 void |
| xfs_iput_new(xfs_inode_t *ip, | xfs_iput_new(xfs_inode_t *ip, |
| uint lock_flags) | uint lock_flags) |
| { | { |
| bhv_vnode_t *vp = XFS_ITOV(ip); | struct inode *inode = ip->i_vnode; |
| struct inode *inode = vn_to_inode(vp); | |
| xfs_itrace_entry(ip); | xfs_itrace_entry(ip); |
| if ((ip->i_d.di_mode == 0)) { | if ((ip->i_d.di_mode == 0)) { |
| ASSERT(!xfs_iflags_test(ip, XFS_IRECLAIMABLE)); | ASSERT(!xfs_iflags_test(ip, XFS_IRECLAIMABLE)); |
| vn_mark_bad(vp); | make_bad_inode(inode); |
| } | } |
| if (inode->i_state & I_NEW) | if (inode->i_state & I_NEW) |
| unlock_new_inode(inode); | unlock_new_inode(inode); |
| if (lock_flags) | if (lock_flags) |
| xfs_iunlock(ip, lock_flags); | xfs_iunlock(ip, lock_flags); |
| VN_RELE(vp); | IRELE(ip); |
| } | } |
| Line 496 xfs_iput_new(xfs_inode_t *ip, | Line 487 xfs_iput_new(xfs_inode_t *ip, |
| void | void |
| xfs_ireclaim(xfs_inode_t *ip) | xfs_ireclaim(xfs_inode_t *ip) |
| { | { |
| bhv_vnode_t *vp; | |
| /* | /* |
| * Remove from old hash list and mount list. | * Remove from old hash list and mount list. |
| */ | */ |
| Line 526 xfs_ireclaim(xfs_inode_t *ip) | Line 515 xfs_ireclaim(xfs_inode_t *ip) |
| /* | /* |
| * Pull our behavior descriptor from the vnode chain. | * Pull our behavior descriptor from the vnode chain. |
| */ | */ |
| vp = XFS_ITOV_NULL(ip); | if (ip->i_vnode) { |
| if (vp) { | ip->i_vnode->i_private = NULL; |
| vn_to_inode(vp)->i_private = NULL; | |
| ip->i_vnode = NULL; | ip->i_vnode = NULL; |
| } | } |