From owner-svn-src-all@FreeBSD.ORG Mon Jul 14 08:34:55 2014 Return-Path: Delivered-To: svn-src-all@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) (using TLSv1 with cipher ADH-AES256-SHA (256/256 bits)) (No client certificate requested) by hub.freebsd.org (Postfix) with ESMTPS id CFD03855; Mon, 14 Jul 2014 08:34:55 +0000 (UTC) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:1900:2254:2068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mx1.freebsd.org (Postfix) with ESMTPS id B08162DA2; Mon, 14 Jul 2014 08:34:55 +0000 (UTC) Received: from svn.freebsd.org ([127.0.1.70]) by svn.freebsd.org (8.14.8/8.14.8) with ESMTP id s6E8YthG028327; Mon, 14 Jul 2014 08:34:55 GMT (envelope-from kib@svn.freebsd.org) Received: (from kib@localhost) by svn.freebsd.org (8.14.8/8.14.8/Submit) id s6E8YsdY028323; Mon, 14 Jul 2014 08:34:54 GMT (envelope-from kib@svn.freebsd.org) Message-Id: <201407140834.s6E8YsdY028323@svn.freebsd.org> From: Konstantin Belousov Date: Mon, 14 Jul 2014 08:34:54 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r268606 - in head/sys: fs/cd9660 fs/msdosfs kern sys X-SVN-Group: head MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-all@freebsd.org X-Mailman-Version: 2.1.18 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: Mon, 14 Jul 2014 08:34:56 -0000 Author: kib Date: Mon Jul 14 08:34:54 2014 New Revision: 268606 URL: http://svnweb.freebsd.org/changeset/base/268606 Log: Generalize vn_get_ino() to allow filesystems to use custom vnode producer, instead of hard-coding VFS_VGET(). New function, which takes callback, is called vn_get_ino_gen(), standard callback for vn_get_ino() is provided. Convert inline copies of vn_get_ino() in msdosfs and cd9660 into the uses of vn_get_ino_gen(). Tested by: pho Sponsored by: The FreeBSD Foundation MFC after: 2 weeks Modified: head/sys/fs/cd9660/cd9660_lookup.c head/sys/fs/msdosfs/msdosfs_lookup.c head/sys/kern/vfs_vnops.c head/sys/sys/vnode.h Modified: head/sys/fs/cd9660/cd9660_lookup.c ============================================================================== --- head/sys/fs/cd9660/cd9660_lookup.c Mon Jul 14 08:17:11 2014 (r268605) +++ head/sys/fs/cd9660/cd9660_lookup.c Mon Jul 14 08:34:54 2014 (r268606) @@ -50,6 +50,23 @@ __FBSDID("$FreeBSD$"); #include #include +struct cd9660_ino_alloc_arg { + ino_t ino; + ino_t i_ino; + struct iso_directory_record *ep; +}; + +static int +cd9660_ino_alloc(struct mount *mp, void *arg, int lkflags, + struct vnode **vpp) +{ + struct cd9660_ino_alloc_arg *dd_arg; + + dd_arg = arg; + return (cd9660_vget_internal(mp, dd_arg->i_ino, lkflags, vpp, + dd_arg->i_ino != dd_arg->ino, dd_arg->ep)); +} + /* * Convert a component of a pathname into a pointer to a locked inode. * This is a very central and rather complicated routine. @@ -104,6 +121,7 @@ cd9660_lookup(ap) doff_t endsearch; /* offset to end directory search */ struct vnode *pdp; /* saved dp during symlink work */ struct vnode *tdp; /* returned by cd9660_vget_internal */ + struct cd9660_ino_alloc_arg dd_arg; u_long bmask; /* block offset mask */ int error; ino_t ino, i_ino; @@ -114,7 +132,6 @@ cd9660_lookup(ap) int res; int assoc, len; char *name; - struct mount *mp; struct vnode **vpp = ap->a_vpp; struct componentname *cnp = ap->a_cnp; int flags = cnp->cn_flags; @@ -368,39 +385,13 @@ found: * it's a relocated directory. */ if (flags & ISDOTDOT) { - /* - * Expanded copy of vn_vget_ino() so that we can use - * cd9660_vget_internal(). - */ - mp = pdp->v_mount; - ltype = VOP_ISLOCKED(pdp); - error = vfs_busy(mp, MBF_NOWAIT); - if (error != 0) { - vfs_ref(mp); - VOP_UNLOCK(pdp, 0); - error = vfs_busy(mp, 0); - vn_lock(pdp, ltype | LK_RETRY); - vfs_rel(mp); - if (error) - return (ENOENT); - if (pdp->v_iflag & VI_DOOMED) { - vfs_unbusy(mp); - return (ENOENT); - } - } - VOP_UNLOCK(pdp, 0); - error = cd9660_vget_internal(vdp->v_mount, i_ino, - cnp->cn_lkflags, &tdp, - i_ino != ino, ep); + dd_arg.ino = ino; + dd_arg.i_ino = i_ino; + dd_arg.ep = ep; + error = vn_vget_ino_gen(pdp, cd9660_ino_alloc, &dd_arg, + cnp->cn_lkflags, &tdp); free(ep2, M_TEMP); - vfs_unbusy(mp); - vn_lock(pdp, ltype | LK_RETRY); - if (pdp->v_iflag & VI_DOOMED) { - if (error == 0) - vput(tdp); - error = ENOENT; - } - if (error) + if (error != 0) return (error); *vpp = tdp; } else if (dp->i_number == i_ino) { Modified: head/sys/fs/msdosfs/msdosfs_lookup.c ============================================================================== --- head/sys/fs/msdosfs/msdosfs_lookup.c Mon Jul 14 08:17:11 2014 (r268605) +++ head/sys/fs/msdosfs/msdosfs_lookup.c Mon Jul 14 08:34:54 2014 (r268606) @@ -63,8 +63,6 @@ static int msdosfs_lookup_(struct vnode *vdp, struct vnode **vpp, struct componentname *cnp, u_int64_t *inum); -static int msdosfs_deget_dotdot(struct vnode *vp, u_long cluster, int blkoff, - struct vnode **rvp); int msdosfs_lookup(struct vop_cachedlookup_args *ap) @@ -73,6 +71,28 @@ msdosfs_lookup(struct vop_cachedlookup_a return (msdosfs_lookup_(ap->a_dvp, ap->a_vpp, ap->a_cnp, NULL)); } +struct deget_dotdot { + u_long cluster; + int blkoff; +}; + +static int +msdosfs_deget_dotdot(struct mount *mp, void *arg, int lkflags, + struct vnode **rvp) +{ + struct deget_dotdot *dd_arg; + struct denode *rdp; + struct msdosfsmount *pmp; + int error; + + pmp = VFSTOMSDOSFS(mp); + dd_arg = arg; + error = deget(pmp, dd_arg->cluster, dd_arg->blkoff, &rdp); + if (error == 0) + *rvp = DETOV(rdp); + return (error); +} + /* * When we search a directory the blocks containing directory entries are * read and examined. The directory entries contain information that would @@ -110,6 +130,7 @@ msdosfs_lookup_(struct vnode *vdp, struc struct msdosfsmount *pmp; struct buf *bp = NULL; struct direntry *dep = NULL; + struct deget_dotdot dd_arg; u_char dosfilename[12]; int flags = cnp->cn_flags; int nameiop = cnp->cn_nameiop; @@ -524,8 +545,11 @@ foundroot: */ pdp = vdp; if (flags & ISDOTDOT) { - error = msdosfs_deget_dotdot(pdp, cluster, blkoff, vpp); - if (error) { + dd_arg.cluster = cluster; + dd_arg.blkoff = blkoff; + error = vn_vget_ino_gen(vdp, msdosfs_deget_dotdot, + &dd_arg, cnp->cn_lkflags, vpp); + if (error != 0) { *vpp = NULL; return (error); } @@ -560,54 +584,6 @@ foundroot: return (0); } -static int -msdosfs_deget_dotdot(struct vnode *vp, u_long cluster, int blkoff, - struct vnode **rvp) -{ - struct mount *mp; - struct msdosfsmount *pmp; - struct denode *rdp; - int ltype, error; - - mp = vp->v_mount; - pmp = VFSTOMSDOSFS(mp); - ltype = VOP_ISLOCKED(vp); - KASSERT(ltype == LK_EXCLUSIVE || ltype == LK_SHARED, - ("msdosfs_deget_dotdot: vp not locked")); - - error = vfs_busy(mp, MBF_NOWAIT); - if (error != 0) { - vfs_ref(mp); - VOP_UNLOCK(vp, 0); - error = vfs_busy(mp, 0); - vn_lock(vp, ltype | LK_RETRY); - vfs_rel(mp); - if (error != 0) - return (ENOENT); - if (vp->v_iflag & VI_DOOMED) { - vfs_unbusy(mp); - return (ENOENT); - } - } - VOP_UNLOCK(vp, 0); - error = deget(pmp, cluster, blkoff, &rdp); - vfs_unbusy(mp); - if (error == 0) - *rvp = DETOV(rdp); - if (*rvp != vp) - vn_lock(vp, ltype | LK_RETRY); - if (vp->v_iflag & VI_DOOMED) { - if (error == 0) { - if (*rvp == vp) - vunref(*rvp); - else - vput(*rvp); - } - error = ENOENT; - } - return (error); -} - /* * dep - directory entry to copy into the directory * ddep - directory to add to Modified: head/sys/kern/vfs_vnops.c ============================================================================== --- head/sys/kern/vfs_vnops.c Mon Jul 14 08:17:11 2014 (r268605) +++ head/sys/kern/vfs_vnops.c Mon Jul 14 08:34:54 2014 (r268606) @@ -1953,12 +1953,30 @@ vn_extattr_rm(struct vnode *vp, int iofl return (error); } +static int +vn_get_ino_alloc_vget(struct mount *mp, void *arg, int lkflags, + struct vnode **rvp) +{ + + return (VFS_VGET(mp, *(ino_t *)arg, lkflags, rvp)); +} + int vn_vget_ino(struct vnode *vp, ino_t ino, int lkflags, struct vnode **rvp) { + + return (vn_vget_ino_gen(vp, vn_get_ino_alloc_vget, &ino, + lkflags, rvp)); +} + +int +vn_vget_ino_gen(struct vnode *vp, vn_get_ino_t alloc, void *alloc_arg, + int lkflags, struct vnode **rvp) +{ struct mount *mp; int ltype, error; + ASSERT_VOP_LOCKED(vp, "vn_vget_ino_get"); mp = vp->v_mount; ltype = VOP_ISLOCKED(vp); KASSERT(ltype == LK_EXCLUSIVE || ltype == LK_SHARED, @@ -1978,12 +1996,17 @@ vn_vget_ino(struct vnode *vp, ino_t ino, } } VOP_UNLOCK(vp, 0); - error = VFS_VGET(mp, ino, lkflags, rvp); + error = alloc(mp, alloc_arg, lkflags, rvp); vfs_unbusy(mp); - vn_lock(vp, ltype | LK_RETRY); + if (*rvp != vp) + vn_lock(vp, ltype | LK_RETRY); if (vp->v_iflag & VI_DOOMED) { - if (error == 0) - vput(*rvp); + if (error == 0) { + if (*rvp == vp) + vunref(vp); + else + vput(*rvp); + } error = ENOENT; } return (error); Modified: head/sys/sys/vnode.h ============================================================================== --- head/sys/sys/vnode.h Mon Jul 14 08:17:11 2014 (r268605) +++ head/sys/sys/vnode.h Mon Jul 14 08:34:54 2014 (r268606) @@ -593,6 +593,8 @@ struct uio; struct vattr; struct vnode; +typedef int (*vn_get_ino_t)(struct mount *, void *, int, struct vnode **); + /* cache_* may belong in namei.h. */ #define cache_enter(dvp, vp, cnp) \ cache_enter_time(dvp, vp, cnp, NULL, NULL) @@ -696,6 +698,8 @@ int vn_extattr_rm(struct vnode *vp, int const char *attrname, struct thread *td); int vn_vget_ino(struct vnode *vp, ino_t ino, int lkflags, struct vnode **rvp); +int vn_vget_ino_gen(struct vnode *vp, vn_get_ino_t alloc, + void *alloc_arg, int lkflags, struct vnode **rvp); int vn_utimes_perm(struct vnode *vp, struct vattr *vap, struct ucred *cred, struct thread *td);