Diff for /xfs-linux/xfs_iget.c between versions 1.235 and 1.236

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;
         }          }
   

Removed from v.1.235  
changed lines
  Added in v.1.236


FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>