Author: kib
Date: Tue Apr 20 10:19:27 2010
New Revision: 206894
URL: http://svn.freebsd.org/changeset/base/206894

Log:
  The cache_enter(9) function shall not be called for doomed dvp.
  Assert this.
  
  In the reported panic, vdestroy() fired the assertion "vp has namecache
  for ..", because pseudofs may end up doing cache_enter() with reclaimed
  dvp, after dotdot lookup temporary unlocked dvp.
  Similar problem exists in ufs_lookup() for "." lookup, when vnode
  lock needs to be upgraded.
  
  Verify that dvp is not reclaimed before calling cache_enter().
  
  Reported and tested by:       pho
  Reviewed by:  kan
  MFC after:    2 weeks

Modified:
  head/sys/fs/pseudofs/pseudofs_vnops.c
  head/sys/kern/vfs_cache.c
  head/sys/ufs/ufs/ufs_lookup.c

Modified: head/sys/fs/pseudofs/pseudofs_vnops.c
==============================================================================
--- head/sys/fs/pseudofs/pseudofs_vnops.c       Tue Apr 20 10:16:44 2010        
(r206893)
+++ head/sys/fs/pseudofs/pseudofs_vnops.c       Tue Apr 20 10:19:27 2010        
(r206894)
@@ -542,7 +542,7 @@ pfs_lookup(struct vop_cachedlookup_args 
 
        if (cnp->cn_flags & ISDOTDOT)
                vn_lock(vn, LK_EXCLUSIVE|LK_RETRY);
-       if (cnp->cn_flags & MAKEENTRY)
+       if (cnp->cn_flags & MAKEENTRY && !(vn->v_iflag & VI_DOOMED))
                cache_enter(vn, *vpp, cnp);
        PFS_RETURN (0);
  failed:

Modified: head/sys/kern/vfs_cache.c
==============================================================================
--- head/sys/kern/vfs_cache.c   Tue Apr 20 10:16:44 2010        (r206893)
+++ head/sys/kern/vfs_cache.c   Tue Apr 20 10:19:27 2010        (r206894)
@@ -611,6 +611,8 @@ cache_enter(dvp, vp, cnp)
        CTR3(KTR_VFS, "cache_enter(%p, %p, %s)", dvp, vp, cnp->cn_nameptr);
        VNASSERT(vp == NULL || (vp->v_iflag & VI_DOOMED) == 0, vp,
            ("cache_enter: Adding a doomed vnode"));
+       VNASSERT(dvp == NULL || (dvp->v_iflag & VI_DOOMED) == 0, dvp,
+           ("cache_enter: Doomed vnode used as src"));
 
        if (!doingcache)
                return;

Modified: head/sys/ufs/ufs/ufs_lookup.c
==============================================================================
--- head/sys/ufs/ufs/ufs_lookup.c       Tue Apr 20 10:16:44 2010        
(r206893)
+++ head/sys/ufs/ufs/ufs_lookup.c       Tue Apr 20 10:19:27 2010        
(r206894)
@@ -704,6 +704,14 @@ found:
                                vn_lock(vdp, LK_UPGRADE | LK_RETRY);
                        else /* if (ltype == LK_SHARED) */
                                vn_lock(vdp, LK_DOWNGRADE | LK_RETRY);
+                       /*
+                        * Relock for the "." case may left us with
+                        * reclaimed vnode.
+                        */
+                       if (vdp->v_iflag & VI_DOOMED) {
+                               vrele(vdp);
+                               return (ENOENT);
+                       }
                }
                *vpp = vdp;
        } else {
_______________________________________________
svn-src-all@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"

Reply via email to