From owner-svn-src-stable-7@FreeBSD.ORG Sat May 16 17:15:26 2009 Return-Path: Delivered-To: svn-src-stable-7@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id DC2D71065670; Sat, 16 May 2009 17:15:26 +0000 (UTC) (envelope-from kib@FreeBSD.org) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:4f8:fff6::2c]) by mx1.freebsd.org (Postfix) with ESMTP id C93328FC18; Sat, 16 May 2009 17:15:26 +0000 (UTC) (envelope-from kib@FreeBSD.org) Received: from svn.freebsd.org (localhost [127.0.0.1]) by svn.freebsd.org (8.14.3/8.14.3) with ESMTP id n4GHFQgE064897; Sat, 16 May 2009 17:15:26 GMT (envelope-from kib@svn.freebsd.org) Received: (from kib@localhost) by svn.freebsd.org (8.14.3/8.14.3/Submit) id n4GHFQvU064896; Sat, 16 May 2009 17:15:26 GMT (envelope-from kib@svn.freebsd.org) Message-Id: <200905161715.n4GHFQvU064896@svn.freebsd.org> From: Konstantin Belousov Date: Sat, 16 May 2009 17:15:26 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-7@freebsd.org X-SVN-Group: stable-7 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Cc: Subject: svn commit: r192200 - in stable/7/sys: . contrib/pf dev/ath/ath_hal dev/cxgb ufs/ufs X-BeenThere: svn-src-stable-7@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: SVN commit messages for only the 7-stable src tree List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sat, 16 May 2009 17:15:27 -0000 Author: kib Date: Sat May 16 17:15:26 2009 New Revision: 192200 URL: http://svn.freebsd.org/changeset/base/192200 Log: MFC r191137: Verify that '..' still exists with the same inode number after VFS_VGET() has returned in ufs_lookup(). MFC r191260: When verifying '..' after VFS_VGET() in ufs_lookup(), do not return error if '..' is still there but changed between lookup and check. Start relookup instead. Modified: stable/7/sys/ (props changed) stable/7/sys/contrib/pf/ (props changed) stable/7/sys/dev/ath/ath_hal/ (props changed) stable/7/sys/dev/cxgb/ (props changed) stable/7/sys/ufs/ufs/ufs_lookup.c Modified: stable/7/sys/ufs/ufs/ufs_lookup.c ============================================================================== --- stable/7/sys/ufs/ufs/ufs_lookup.c Sat May 16 15:21:08 2009 (r192199) +++ stable/7/sys/ufs/ufs/ufs_lookup.c Sat May 16 17:15:26 2009 (r192200) @@ -77,6 +77,9 @@ SYSCTL_INT(_debug, OID_AUTO, dircheck, C /* true if old FS format...*/ #define OFSFMT(vp) ((vp)->v_mount->mnt_maxsymlinklen <= 0) +static int ufs_lookup_(struct vnode *, struct vnode **, struct componentname *, + ino_t *); + /* * Convert a component of a pathname into a pointer to a locked inode. * This is a very central and rather complicated routine. @@ -130,7 +133,14 @@ ufs_lookup(ap) struct componentname *a_cnp; } */ *ap; { - struct vnode *vdp; /* vnode for directory being searched */ + + return (ufs_lookup_(ap->a_dvp, ap->a_vpp, ap->a_cnp, NULL)); +} + +static int +ufs_lookup_(struct vnode *vdp, struct vnode **vpp, struct componentname *cnp, + ino_t *dd_ino) +{ struct inode *dp; /* inode for directory being searched */ struct buf *bp; /* a buffer of directory entries */ struct direct *ep; /* the current directory entry */ @@ -150,24 +160,16 @@ ufs_lookup(ap) doff_t enduseful; /* pointer past last used dir slot */ u_long bmask; /* block offset mask */ int namlen, error; - struct vnode **vpp = ap->a_vpp; - struct componentname *cnp = ap->a_cnp; struct ucred *cred = cnp->cn_cred; int flags = cnp->cn_flags; int nameiop = cnp->cn_nameiop; struct thread *td = cnp->cn_thread; - ino_t ino; + ino_t ino, ino1; int ltype; - bp = NULL; - slotoffset = -1; -/* - * XXX there was a soft-update diff about this I couldn't merge. - * I think this was the equiv. - */ - *vpp = NULL; + if (vpp != NULL) + *vpp = NULL; - vdp = ap->a_dvp; dp = VTOI(vdp); /* @@ -178,6 +180,12 @@ ufs_lookup(ap) */ vnode_create_vobject(vdp, DIP(dp, i_size), cnp->cn_thread); + bmask = VFSTOUFS(vdp->v_mount)->um_mountp->mnt_stat.f_iosize - 1; + +restart: + bp = NULL; + slotoffset = -1; + /* * We now have a segment name to search for, and a directory to search. * @@ -195,7 +203,6 @@ ufs_lookup(ap) slotstatus = NONE; slotneeded = DIRECTSIZ(cnp->cn_namelen); } - bmask = VFSTOUFS(vdp->v_mount)->um_mountp->mnt_stat.f_iosize - 1; #ifdef UFS_DIRHASH /* @@ -364,7 +371,7 @@ foundentry: slotoffset = i_offset; slotsize = ep->d_reclen; enduseful = dp->i_size; - ap->a_cnp->cn_flags |= ISWHITEOUT; + cnp->cn_flags |= ISWHITEOUT; numdirpasses--; goto notfound; } @@ -398,8 +405,8 @@ notfound: */ if ((nameiop == CREATE || nameiop == RENAME || (nameiop == DELETE && - (ap->a_cnp->cn_flags & DOWHITEOUT) && - (ap->a_cnp->cn_flags & ISWHITEOUT))) && + (cnp->cn_flags & DOWHITEOUT) && + (cnp->cn_flags & ISWHITEOUT))) && (flags & ISLASTCN) && dp->i_effnlink != 0) { /* * Access for write is interpreted as allowing @@ -454,7 +461,7 @@ notfound: * Insert name into cache (as non-existent) if appropriate. */ if ((cnp->cn_flags & MAKEENTRY) && nameiop != CREATE) - cache_enter(vdp, *vpp, cnp); + cache_enter(vdp, NULL, cnp); return (ENOENT); found: @@ -480,6 +487,11 @@ found: if ((flags & ISLASTCN) && nameiop == LOOKUP) dp->i_diroff = i_offset &~ (DIRBLKSIZ - 1); + if (dd_ino != NULL) { + *dd_ino = ino; + return (0); + } + /* * If deleting, and at end of pathname, return * parameters which can be used to remove file. @@ -581,6 +593,22 @@ found: error = vn_vget_ino(pdp, ino, cnp->cn_lkflags, &tdp); if (error) return (error); + + /* + * Recheck that ".." entry in the vdp directory points + * to the inode we looked up before vdp lock was + * dropped. + */ + error = ufs_lookup_(pdp, NULL, cnp, &ino1); + if (error) { + vput(tdp); + return (error); + } + if (ino1 != ino) { + vput(tdp); + goto restart; + } + *vpp = tdp; } else if (dp->i_number == ino) { VREF(vdp); /* we want ourself, ie "." */