From owner-svn-src-all@FreeBSD.ORG Sun Apr 19 05:34:07 2009 Return-Path: Delivered-To: svn-src-all@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id E94FF1065670; Sun, 19 Apr 2009 05:34:07 +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 CDF928FC13; Sun, 19 Apr 2009 05:34:07 +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 n3J5Y7pH099625; Sun, 19 Apr 2009 05:34:07 GMT (envelope-from kib@svn.freebsd.org) Received: (from kib@localhost) by svn.freebsd.org (8.14.3/8.14.3/Submit) id n3J5Y701099624; Sun, 19 Apr 2009 05:34:07 GMT (envelope-from kib@svn.freebsd.org) Message-Id: <200904190534.n3J5Y701099624@svn.freebsd.org> From: Konstantin Belousov Date: Sun, 19 Apr 2009 05:34:07 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org X-SVN-Group: head MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Cc: Subject: svn commit: r191260 - head/sys/ufs/ufs X-BeenThere: svn-src-all@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: "SVN commit messages for the entire src tree \(except for " user" and " projects" \)" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sun, 19 Apr 2009 05:34:08 -0000 Author: kib Date: Sun Apr 19 05:34:07 2009 New Revision: 191260 URL: http://svn.freebsd.org/changeset/base/191260 Log: 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. Rename is supposed to change '..' reference atomically, so transient failures introduced by r191137 are wrong. While rearranging the code to allow lookup restart in ufs_lookup(), remove the comment that only distracts the reader. Noted and reviewed by: tegge Also reported by: pho MFC after: 1 month Modified: head/sys/ufs/ufs/ufs_lookup.c Modified: head/sys/ufs/ufs/ufs_lookup.c ============================================================================== --- head/sys/ufs/ufs/ufs_lookup.c Sun Apr 19 04:44:05 2009 (r191259) +++ head/sys/ufs/ufs/ufs_lookup.c Sun Apr 19 05:34:07 2009 (r191260) @@ -78,7 +78,7 @@ SYSCTL_INT(_debug, OID_AUTO, dircheck, C #define OFSFMT(vp) ((vp)->v_mount->mnt_maxsymlinklen <= 0) static int ufs_lookup_(struct vnode *, struct vnode **, struct componentname *, - ino_t); + ino_t *); /* * Convert a component of a pathname into a pointer to a locked inode. @@ -134,12 +134,12 @@ ufs_lookup(ap) } */ *ap; { - return (ufs_lookup_(ap->a_dvp, ap->a_vpp, ap->a_cnp, 0)); + 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) + ino_t *dd_ino) { struct inode *dp; /* inode for directory being searched */ struct buf *bp; /* a buffer of directory entries */ @@ -163,15 +163,9 @@ ufs_lookup_(struct vnode *vdp, struct vn struct ucred *cred = cnp->cn_cred; int flags = cnp->cn_flags; int nameiop = cnp->cn_nameiop; - 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. - */ if (vpp != NULL) *vpp = NULL; @@ -185,6 +179,12 @@ ufs_lookup_(struct vnode *vdp, struct vn */ 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. * @@ -202,7 +202,6 @@ ufs_lookup_(struct vnode *vdp, struct vn slotstatus = NONE; slotneeded = DIRECTSIZ(cnp->cn_namelen); } - bmask = VFSTOUFS(vdp->v_mount)->um_mountp->mnt_stat.f_iosize - 1; #ifdef UFS_DIRHASH /* @@ -487,9 +486,8 @@ found: if ((flags & ISLASTCN) && nameiop == LOOKUP) dp->i_diroff = i_offset &~ (DIRBLKSIZ - 1); - if (dd_ino != 0) { - if (ino != dd_ino) - return (ENOENT); + if (dd_ino != NULL) { + *dd_ino = ino; return (0); } @@ -600,11 +598,15 @@ found: * to the inode we looked up before vdp lock was * dropped. */ - error = ufs_lookup_(pdp, NULL, cnp, ino); + 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) {