Date: Fri, 12 Feb 2021 01:07:04 GMT From: Konstantin Belousov <kib@FreeBSD.org> To: src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-main@FreeBSD.org Subject: git: 5952c86c78b1 - main - ffs_inotovp(): interface to convert (ino, gen) into alive vnode Message-ID: <202102120107.11C1744G070451@gitrepo.freebsd.org>
next in thread | raw e-mail | index | archive | help
The branch main has been updated by kib: URL: https://cgit.FreeBSD.org/src/commit/?id=5952c86c78b177b5e904bf139e6b56519897c7e0 commit 5952c86c78b177b5e904bf139e6b56519897c7e0 Author: Konstantin Belousov <kib@FreeBSD.org> AuthorDate: 2021-01-26 11:52:59 +0000 Commit: Konstantin Belousov <kib@FreeBSD.org> CommitDate: 2021-02-12 01:02:20 +0000 ffs_inotovp(): interface to convert (ino, gen) into alive vnode It generalizes the VFS_FHTOVP() interface, making it possible to fetch the inode without faking filehandle. Also it adds the ffs flags argument which allows to control ffs_vgetf() call. Requested by: mckusick Reviewed by: chs, mckusick Tested by: pho MFC after: 2 weeks Sponsored by: The FreeBSD Foundation --- sys/ufs/ffs/ffs_extern.h | 2 ++ sys/ufs/ffs/ffs_vfsops.c | 44 ++++++++++++++++++++++++++++++++------------ sys/ufs/ufs/ufs_extern.h | 2 +- sys/ufs/ufs/ufs_vfsops.c | 21 +++++---------------- 4 files changed, 40 insertions(+), 29 deletions(-) diff --git a/sys/ufs/ffs/ffs_extern.h b/sys/ufs/ffs/ffs_extern.h index bdb3f533e1ad..9694489266b6 100644 --- a/sys/ufs/ffs/ffs_extern.h +++ b/sys/ufs/ffs/ffs_extern.h @@ -80,6 +80,8 @@ int ffs_freefile(struct ufsmount *, struct fs *, struct vnode *, ino_t, void ffs_fserr(struct fs *, ino_t, char *); int ffs_getcg(struct fs *, struct vnode *, u_int, int, struct buf **, struct cg **); +int ffs_inotovp(struct mount *, ino_t, u_int64_t, int, struct vnode **, + int); int ffs_isblock(struct fs *, u_char *, ufs1_daddr_t); int ffs_isfreeblock(struct fs *, u_char *, ufs1_daddr_t); void ffs_oldfscompat_write(struct fs *, struct ufsmount *); diff --git a/sys/ufs/ffs/ffs_vfsops.c b/sys/ufs/ffs/ffs_vfsops.c index 91b8c30f0919..596e2f4b4b5f 100644 --- a/sys/ufs/ffs/ffs_vfsops.c +++ b/sys/ufs/ffs/ffs_vfsops.c @@ -2153,35 +2153,55 @@ ffs_fhtovp(mp, fhp, flags, vpp) struct vnode **vpp; { struct ufid *ufhp; + + ufhp = (struct ufid *)fhp; + return (ffs_inotovp(mp, ufhp->ufid_ino, ufhp->ufid_gen, flags, + vpp, 0)); +} + +int +ffs_inotovp(mp, ino, gen, lflags, vpp, ffs_flags) + struct mount *mp; + ino_t ino; + u_int64_t gen; + int lflags; + struct vnode **vpp; + int ffs_flags; +{ struct ufsmount *ump; + struct vnode *nvp; struct fs *fs; struct cg *cgp; struct buf *bp; - ino_t ino; u_int cg; int error; - ufhp = (struct ufid *)fhp; - ino = ufhp->ufid_ino; ump = VFSTOUFS(mp); fs = ump->um_fs; if (ino < UFS_ROOTINO || ino >= fs->fs_ncg * fs->fs_ipg) return (ESTALE); + /* * Need to check if inode is initialized because UFS2 does lazy * initialization and nfs_fhtovp can offer arbitrary inode numbers. */ - if (fs->fs_magic != FS_UFS2_MAGIC) - return (ufs_fhtovp(mp, ufhp, flags, vpp)); - cg = ino_to_cg(fs, ino); - if ((error = ffs_getcg(fs, ump->um_devvp, cg, 0, &bp, &cgp)) != 0) - return (error); - if (ino >= cg * fs->fs_ipg + cgp->cg_initediblk) { + if (fs->fs_magic == FS_UFS2_MAGIC) { + cg = ino_to_cg(fs, ino); + error = ffs_getcg(fs, ump->um_devvp, cg, 0, &bp, &cgp); + if (error != 0) + return (error); + if (ino >= cg * fs->fs_ipg + cgp->cg_initediblk) { + brelse(bp); + return (ESTALE); + } brelse(bp); - return (ESTALE); } - brelse(bp); - return (ufs_fhtovp(mp, ufhp, flags, vpp)); + + error = ffs_vgetf(mp, ino, lflags, &nvp, ffs_flags); + if (error == 0) + error = ufs_fhtovp(mp, nvp, gen); + *vpp = error == 0 ? nvp : NULLVP; + return (error); } /* diff --git a/sys/ufs/ufs/ufs_extern.h b/sys/ufs/ufs/ufs_extern.h index a28fcffabd2e..ab26750455e8 100644 --- a/sys/ufs/ufs/ufs_extern.h +++ b/sys/ufs/ufs/ufs_extern.h @@ -59,7 +59,7 @@ int ufs_bmap(struct vop_bmap_args *); int ufs_bmaparray(struct vnode *, ufs2_daddr_t, ufs2_daddr_t *, struct buf *, int *, int *); int ufs_bmap_seekdata(struct vnode *, off_t *); -int ufs_fhtovp(struct mount *, struct ufid *, int, struct vnode **); +int ufs_fhtovp(struct mount *, struct vnode *, u_int64_t); int ufs_checkpath(ino_t, ino_t, struct inode *, struct ucred *, ino_t *); void ufs_dirbad(struct inode *, doff_t, char *); int ufs_dirbadentry(struct vnode *, struct direct *, int); diff --git a/sys/ufs/ufs/ufs_vfsops.c b/sys/ufs/ufs/ufs_vfsops.c index 4813ac7db763..1a63e92b3e2c 100644 --- a/sys/ufs/ufs/ufs_vfsops.c +++ b/sys/ufs/ufs/ufs_vfsops.c @@ -222,31 +222,20 @@ ufs_uninit(vfsp) * Call the VFS_CHECKEXP beforehand to verify access. */ int -ufs_fhtovp(mp, ufhp, flags, vpp) +ufs_fhtovp(mp, nvp, gen) struct mount *mp; - struct ufid *ufhp; - int flags; - struct vnode **vpp; + struct vnode *nvp; + u_int64_t gen; { struct inode *ip; - struct vnode *nvp; - int error; - error = VFS_VGET(mp, ufhp->ufid_ino, flags, &nvp); - if (error) { - *vpp = NULLVP; - return (error); - } ip = VTOI(nvp); - if (ip->i_mode == 0 || ip->i_gen != ufhp->ufid_gen || - ip->i_effnlink <= 0) { + if (ip->i_mode == 0 || ip->i_gen != gen || ip->i_effnlink <= 0) { if (ip->i_mode == 0) vgone(nvp); vput(nvp); - *vpp = NULLVP; return (ESTALE); } - *vpp = nvp; - vnode_create_vobject(*vpp, DIP(ip, i_size), curthread); + vnode_create_vobject(nvp, DIP(ip, i_size), curthread); return (0); }
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?202102120107.11C1744G070451>