git: 6ea02becc78c - stable/13 - vfs: Export get_next_dirent() as vn_dir_next_dirent()

From: Konstantin Belousov <kib_at_FreeBSD.org>
Date: Fri, 05 May 2023 06:38:55 UTC
The branch stable/13 has been updated by kib:

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

commit 6ea02becc78c1885ae13713a94e83a5160e63396
Author:     Olivier Certner <olce.freebsd@certner.fr>
AuthorDate: 2023-04-23 07:47:58 +0000
Commit:     Konstantin Belousov <kib@FreeBSD.org>
CommitDate: 2023-05-05 06:20:58 +0000

    vfs: Export get_next_dirent() as vn_dir_next_dirent()
    
    (cherry picked from commit 6bce3f23d0aa045d61c0ec8d27100eb186a33375)
---
 sys/kern/vfs_default.c | 73 +++-----------------------------------------------
 sys/kern/vfs_vnops.c   | 62 ++++++++++++++++++++++++++++++++++++++++++
 sys/sys/vnode.h        |  3 +++
 3 files changed, 69 insertions(+), 69 deletions(-)

diff --git a/sys/kern/vfs_default.c b/sys/kern/vfs_default.c
index 6201426d582c..502a81d3036c 100644
--- a/sys/kern/vfs_default.c
+++ b/sys/kern/vfs_default.c
@@ -75,15 +75,9 @@ __FBSDID("$FreeBSD$");
 static int	vop_nolookup(struct vop_lookup_args *);
 static int	vop_norename(struct vop_rename_args *);
 static int	vop_nostrategy(struct vop_strategy_args *);
-static int	get_next_dirent(struct vnode *vp, struct dirent **dpp,
-				char *dirbuf, int dirbuflen, off_t *off,
-				char **cpos, int *len, int *eofflag,
-				struct thread *td);
 static int	dirent_exists(struct vnode *vp, const char *dirname,
 			      struct thread *td);
 
-#define DIRENT_MINSIZE (sizeof(struct dirent) - (MAXNAMLEN+1) + 4)
-
 static int vop_stdis_text(struct vop_is_text_args *ap);
 static int vop_stdunset_text(struct vop_unset_text_args *ap);
 static int vop_stdadd_writecount(struct vop_add_writecount_args *ap);
@@ -280,65 +274,6 @@ vop_nostrategy (struct vop_strategy_args *ap)
 	return (EOPNOTSUPP);
 }
 
-static int
-get_next_dirent(struct vnode *vp, struct dirent **dpp, char *dirbuf,
-		int dirbuflen, off_t *off, char **cpos, int *len,
-		int *eofflag, struct thread *td)
-{
-	int error, reclen;
-	struct uio uio;
-	struct iovec iov;
-	struct dirent *dp;
-
-	KASSERT(VOP_ISLOCKED(vp), ("vp %p is not locked", vp));
-	KASSERT(vp->v_type == VDIR, ("vp %p is not a directory", vp));
-
-	if (*len == 0) {
-		iov.iov_base = dirbuf;
-		iov.iov_len = dirbuflen;
-
-		uio.uio_iov = &iov;
-		uio.uio_iovcnt = 1;
-		uio.uio_offset = *off;
-		uio.uio_resid = dirbuflen;
-		uio.uio_segflg = UIO_SYSSPACE;
-		uio.uio_rw = UIO_READ;
-		uio.uio_td = td;
-
-		*eofflag = 0;
-
-#ifdef MAC
-		error = mac_vnode_check_readdir(td->td_ucred, vp);
-		if (error == 0)
-#endif
-			error = VOP_READDIR(vp, &uio, td->td_ucred, eofflag,
-		    		NULL, NULL);
-		if (error)
-			return (error);
-
-		*off = uio.uio_offset;
-
-		*cpos = dirbuf;
-		*len = (dirbuflen - uio.uio_resid);
-
-		if (*len == 0)
-			return (ENOENT);
-	}
-
-	dp = (struct dirent *)(*cpos);
-	reclen = dp->d_reclen;
-	*dpp = dp;
-
-	/* check for malformed directory.. */
-	if (reclen < DIRENT_MINSIZE)
-		return (EINVAL);
-
-	*cpos += reclen;
-	*len -= reclen;
-
-	return (0);
-}
-
 /*
  * Check if a named file exists in a given directory vnode.
  */
@@ -368,8 +303,8 @@ dirent_exists(struct vnode *vp, const char *dirname, struct thread *td)
 	off = 0;
 	len = 0;
 	do {
-		error = get_next_dirent(vp, &dp, dirbuf, dirbuflen, &off,
-					&cpos, &len, &eofflag, td);
+		error = vn_dir_next_dirent(vp, &dp, dirbuf, dirbuflen, &off,
+		    &cpos, &len, &eofflag, td);
 		if (error)
 			goto out;
 
@@ -806,8 +741,8 @@ vop_stdvptocnp(struct vop_vptocnp_args *ap)
 	len = 0;
 	do {
 		/* call VOP_READDIR of parent */
-		error = get_next_dirent(*dvp, &dp, dirbuf, dirbuflen, &off,
-					&cpos, &len, &eofflag, td);
+		error = vn_dir_next_dirent(*dvp, &dp, dirbuf, dirbuflen, &off,
+		    &cpos, &len, &eofflag, td);
 		if (error)
 			goto out;
 
diff --git a/sys/kern/vfs_vnops.c b/sys/kern/vfs_vnops.c
index 215c9d1cc0cc..c35370d9d6b3 100644
--- a/sys/kern/vfs_vnops.c
+++ b/sys/kern/vfs_vnops.c
@@ -65,6 +65,7 @@ __FBSDID("$FreeBSD$");
 #include <sys/mutex.h>
 #include <sys/namei.h>
 #include <sys/vnode.h>
+#include <sys/dirent.h>
 #include <sys/bio.h>
 #include <sys/buf.h>
 #include <sys/filio.h>
@@ -3594,6 +3595,67 @@ vn_fallocate(struct file *fp, off_t offset, off_t len, struct thread *td)
 	return (error);
 }
 
+#define DIRENT_MINSIZE (sizeof(struct dirent) - (MAXNAMLEN+1) + 4)
+
+int
+vn_dir_next_dirent(struct vnode *vp, struct dirent **dpp, char *dirbuf,
+    int dirbuflen, off_t *off, char **cpos, int *len,
+    int *eofflag, struct thread *td)
+{
+	int error, reclen;
+	struct uio uio;
+	struct iovec iov;
+	struct dirent *dp;
+
+	KASSERT(VOP_ISLOCKED(vp), ("vp %p is not locked", vp));
+	KASSERT(vp->v_type == VDIR, ("vp %p is not a directory", vp));
+
+	if (*len == 0) {
+		iov.iov_base = dirbuf;
+		iov.iov_len = dirbuflen;
+
+		uio.uio_iov = &iov;
+		uio.uio_iovcnt = 1;
+		uio.uio_offset = *off;
+		uio.uio_resid = dirbuflen;
+		uio.uio_segflg = UIO_SYSSPACE;
+		uio.uio_rw = UIO_READ;
+		uio.uio_td = td;
+
+		*eofflag = 0;
+
+#ifdef MAC
+		error = mac_vnode_check_readdir(td->td_ucred, vp);
+		if (error == 0)
+#endif
+			error = VOP_READDIR(vp, &uio, td->td_ucred, eofflag,
+		    		NULL, NULL);
+		if (error)
+			return (error);
+
+		*off = uio.uio_offset;
+
+		*cpos = dirbuf;
+		*len = (dirbuflen - uio.uio_resid);
+
+		if (*len == 0)
+			return (ENOENT);
+	}
+
+	dp = (struct dirent *)(*cpos);
+	reclen = dp->d_reclen;
+	*dpp = dp;
+
+	/* check for malformed directory.. */
+	if (reclen < DIRENT_MINSIZE)
+		return (EINVAL);
+
+	*cpos += reclen;
+	*len -= reclen;
+
+	return (0);
+}
+
 static u_long vn_lock_pair_pause_cnt;
 SYSCTL_ULONG(_debug, OID_AUTO, vn_lock_pair_pause, CTLFLAG_RD,
     &vn_lock_pair_pause_cnt, 0,
diff --git a/sys/sys/vnode.h b/sys/sys/vnode.h
index 37cafdb0d5ae..d5d2776b2f5e 100644
--- a/sys/sys/vnode.h
+++ b/sys/sys/vnode.h
@@ -1096,6 +1096,9 @@ void vfs_hash_remove(struct vnode *vp);
 
 int vfs_kqfilter(struct vop_kqfilter_args *);
 struct dirent;
+int vn_dir_next_dirent(struct vnode *vp, struct dirent **dpp, char *dirbuf,
+    int dirbuflen, off_t *off, char **cpos, int *len,
+    int *eofflag, struct thread *td);
 int vfs_read_dirent(struct vop_readdir_args *ap, struct dirent *dp, off_t off);
 int vfs_emptydir(struct vnode *vp);