git: abbb57d5a647 - main - vfs: Introduce vn_bmap_seekhole_locked()

Ka Ho Ng khng at FreeBSD.org
Thu Aug 5 15:23:35 UTC 2021


The branch main has been updated by khng:

URL: https://cgit.FreeBSD.org/src/commit/?id=abbb57d5a647f91847a860bd25b4f109c3abb390

commit abbb57d5a647f91847a860bd25b4f109c3abb390
Author:     Ka Ho Ng <khng at FreeBSD.org>
AuthorDate: 2021-08-04 19:20:59 +0000
Commit:     Ka Ho Ng <khng at FreeBSD.org>
CommitDate: 2021-08-05 14:52:26 +0000

    vfs: Introduce vn_bmap_seekhole_locked()
    
    vn_bmap_seekhole_locked() is factored out version of vn_bmap_seekhole().
    This variant requires shared vnode lock being held around the call.
    
    Sponsored by:   The FreeBSD Foundation
    Reviewed by:    kib, markj
    Differential Revision:  https://reviews.freebsd.org/D31404
---
 sys/kern/vfs_vnops.c | 36 +++++++++++++++++++++++++-----------
 sys/sys/vnode.h      |  2 ++
 2 files changed, 27 insertions(+), 11 deletions(-)

diff --git a/sys/kern/vfs_vnops.c b/sys/kern/vfs_vnops.c
index b7e53add5a35..ccc468d71737 100644
--- a/sys/kern/vfs_vnops.c
+++ b/sys/kern/vfs_vnops.c
@@ -2425,7 +2425,8 @@ vn_pages_remove(struct vnode *vp, vm_pindex_t start, vm_pindex_t end)
 }
 
 int
-vn_bmap_seekhole(struct vnode *vp, u_long cmd, off_t *off, struct ucred *cred)
+vn_bmap_seekhole_locked(struct vnode *vp, u_long cmd, off_t *off,
+    struct ucred *cred)
 {
 	struct vattr va;
 	daddr_t bn, bnp;
@@ -2434,21 +2435,20 @@ vn_bmap_seekhole(struct vnode *vp, u_long cmd, off_t *off, struct ucred *cred)
 	int error;
 
 	KASSERT(cmd == FIOSEEKHOLE || cmd == FIOSEEKDATA,
-	    ("Wrong command %lu", cmd));
+	    ("%s: Wrong command %lu", __func__, cmd));
+	ASSERT_VOP_LOCKED(vp, "vn_bmap_seekhole_locked");
 
-	if (vn_lock(vp, LK_SHARED) != 0)
-		return (EBADF);
 	if (vp->v_type != VREG) {
 		error = ENOTTY;
-		goto unlock;
+		goto out;
 	}
 	error = VOP_GETATTR(vp, &va, cred);
 	if (error != 0)
-		goto unlock;
+		goto out;
 	noff = *off;
 	if (noff >= va.va_size) {
 		error = ENXIO;
-		goto unlock;
+		goto out;
 	}
 	bsize = vp->v_mount->mnt_stat.f_iosize;
 	for (bn = noff / bsize; noff < va.va_size; bn++, noff += bsize -
@@ -2456,14 +2456,14 @@ vn_bmap_seekhole(struct vnode *vp, u_long cmd, off_t *off, struct ucred *cred)
 		error = VOP_BMAP(vp, bn, NULL, &bnp, NULL, NULL);
 		if (error == EOPNOTSUPP) {
 			error = ENOTTY;
-			goto unlock;
+			goto out;
 		}
 		if ((bnp == -1 && cmd == FIOSEEKHOLE) ||
 		    (bnp != -1 && cmd == FIOSEEKDATA)) {
 			noff = bn * bsize;
 			if (noff < *off)
 				noff = *off;
-			goto unlock;
+			goto out;
 		}
 	}
 	if (noff > va.va_size)
@@ -2471,13 +2471,27 @@ vn_bmap_seekhole(struct vnode *vp, u_long cmd, off_t *off, struct ucred *cred)
 	/* noff == va.va_size. There is an implicit hole at the end of file. */
 	if (cmd == FIOSEEKDATA)
 		error = ENXIO;
-unlock:
-	VOP_UNLOCK(vp);
+out:
 	if (error == 0)
 		*off = noff;
 	return (error);
 }
 
+int
+vn_bmap_seekhole(struct vnode *vp, u_long cmd, off_t *off, struct ucred *cred)
+{
+	int error;
+
+	KASSERT(cmd == FIOSEEKHOLE || cmd == FIOSEEKDATA,
+	    ("%s: Wrong command %lu", __func__, cmd));
+
+	if (vn_lock(vp, LK_SHARED) != 0)
+		return (EBADF);
+	error = vn_bmap_seekhole_locked(vp, cmd, off, cred);
+	VOP_UNLOCK(vp);
+	return (error);
+}
+
 int
 vn_seek(struct file *fp, off_t offset, int whence, struct thread *td)
 {
diff --git a/sys/sys/vnode.h b/sys/sys/vnode.h
index 1f2d74fdf5f1..702fd6623e6a 100644
--- a/sys/sys/vnode.h
+++ b/sys/sys/vnode.h
@@ -731,6 +731,8 @@ void	vunref(struct vnode *);
 void	vn_printf(struct vnode *vp, const char *fmt, ...) __printflike(2,3);
 int	vrecycle(struct vnode *vp);
 int	vrecyclel(struct vnode *vp);
+int	vn_bmap_seekhole_locked(struct vnode *vp, u_long cmd, off_t *off,
+	    struct ucred *cred);
 int	vn_bmap_seekhole(struct vnode *vp, u_long cmd, off_t *off,
 	    struct ucred *cred);
 int	vn_close(struct vnode *vp,


More information about the dev-commits-src-all mailing list