git: 85f964f75eea - stable/14 - smbfs: Set eofflag in VOP_READDIR

From: Mark Johnston <markj_at_FreeBSD.org>
Date: Tue, 12 Aug 2025 12:56:12 UTC
The branch stable/14 has been updated by markj:

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

commit 85f964f75eea1f67fe2ae661014770c22adf41fd
Author:     Mark Johnston <markj@FreeBSD.org>
AuthorDate: 2025-07-23 16:19:44 +0000
Commit:     Mark Johnston <markj@FreeBSD.org>
CommitDate: 2025-08-12 12:49:42 +0000

    smbfs: Set eofflag in VOP_READDIR
    
    MFC after:      2 weeks
    
    (cherry picked from commit 619308b6fe26f56fc71c6255b13fcd9a6b8ae1f1)
---
 sys/fs/smbfs/smbfs_io.c    | 20 +++++++++++++-------
 sys/fs/smbfs/smbfs_node.h  |  2 +-
 sys/fs/smbfs/smbfs_vnops.c |  6 ++----
 3 files changed, 16 insertions(+), 12 deletions(-)

diff --git a/sys/fs/smbfs/smbfs_io.c b/sys/fs/smbfs/smbfs_io.c
index 35454998fc8e..8c484381ed59 100644
--- a/sys/fs/smbfs/smbfs_io.c
+++ b/sys/fs/smbfs/smbfs_io.c
@@ -71,7 +71,7 @@ SYSCTL_INT(_vfs_smbfs, OID_AUTO, fastlookup, CTLFLAG_RW, &smbfs_fastlookup, 0, "
 #define DE_SIZE	(sizeof(struct dirent))
 
 static int
-smbfs_readvdir(struct vnode *vp, struct uio *uio, struct ucred *cred)
+smbfs_readvdir(struct vnode *vp, struct uio *uio, struct ucred *cred, int *eofp)
 {
 	struct dirent de;
 	struct componentname cn;
@@ -86,6 +86,8 @@ smbfs_readvdir(struct vnode *vp, struct uio *uio, struct ucred *cred)
 	SMBVDEBUG("dirname='%s'\n", np->n_name);
 	scred = smbfs_malloc_scred();
 	smb_makescred(scred, uio->uio_td, cred);
+	if (eofp != NULL)
+		*eofp = 0;
 	offset = uio->uio_offset / DE_SIZE;	/* offset in the directory */
 	limit = uio->uio_resid / DE_SIZE;
 	if (uio->uio_resid < DE_SIZE || uio->uio_offset < 0) {
@@ -138,8 +140,7 @@ smbfs_readvdir(struct vnode *vp, struct uio *uio, struct ucred *cred)
 		if (error) {
 			smbfs_findclose(np->n_dirseq, scred);
 			np->n_dirseq = NULL;
-			error = ENOENT ? 0 : error;
-			goto out;
+			goto out1;
 		}
 	}
 	error = 0;
@@ -170,16 +171,21 @@ smbfs_readvdir(struct vnode *vp, struct uio *uio, struct ucred *cred)
 		if (error)
 			break;
 	}
-	if (error == ENOENT)
-		error = 0;
 	uio->uio_offset = offset * DE_SIZE;
+out1:
+	if (error == ENOENT) {
+		if (eofp != NULL)
+			*eofp = 1;
+		error = 0;
+	}
 out:
 	smbfs_free_scred(scred);
 	return error;
 }
 
 int
-smbfs_readvnode(struct vnode *vp, struct uio *uiop, struct ucred *cred)
+smbfs_readvnode(struct vnode *vp, struct uio *uiop, struct ucred *cred,
+    int *eofp)
 {
 	struct smbmount *smp = VFSTOSMBFS(vp->v_mount);
 	struct smbnode *np = VTOSMB(vp);
@@ -209,7 +215,7 @@ smbfs_readvnode(struct vnode *vp, struct uio *uiop, struct ucred *cred)
 		lks = LK_EXCLUSIVE;	/* lockstatus(vp->v_vnlock); */
 		if (lks == LK_SHARED)
 			vn_lock(vp, LK_UPGRADE | LK_RETRY);
-		error = smbfs_readvdir(vp, uiop, cred);
+		error = smbfs_readvdir(vp, uiop, cred, eofp);
 		if (lks == LK_SHARED)
 			vn_lock(vp, LK_DOWNGRADE | LK_RETRY);
 		return error;
diff --git a/sys/fs/smbfs/smbfs_node.h b/sys/fs/smbfs/smbfs_node.h
index f28f0007100a..8c8ce038b913 100644
--- a/sys/fs/smbfs/smbfs_node.h
+++ b/sys/fs/smbfs/smbfs_node.h
@@ -93,7 +93,7 @@ u_int32_t smbfs_hash(const u_char *name, int nmlen);
 
 int  smbfs_getpages(struct vop_getpages_args *);
 int  smbfs_putpages(struct vop_putpages_args *);
-int  smbfs_readvnode(struct vnode *vp, struct uio *uiop, struct ucred *cred);
+int  smbfs_readvnode(struct vnode *vp, struct uio *uiop, struct ucred *cred, int *eofp);
 int  smbfs_writevnode(struct vnode *vp, struct uio *uiop, struct ucred *cred, int ioflag);
 void smbfs_attr_cacheenter(struct vnode *vp, struct smbfattr *fap);
 int  smbfs_attr_cachelookup(struct vnode *vp ,struct vattr *va);
diff --git a/sys/fs/smbfs/smbfs_vnops.c b/sys/fs/smbfs/smbfs_vnops.c
index c30995508c00..1fccee7983c6 100644
--- a/sys/fs/smbfs/smbfs_vnops.c
+++ b/sys/fs/smbfs/smbfs_vnops.c
@@ -466,7 +466,7 @@ smbfs_read(struct vop_read_args *ap)
 	SMBVDEBUG("\n");
 	if (vp->v_type != VREG && vp->v_type != VDIR)
 		return EPERM;
-	return smbfs_readvnode(vp, uio, ap->a_cred);
+	return smbfs_readvnode(vp, uio, ap->a_cred, NULL);
 }
 
 static int
@@ -748,7 +748,6 @@ smbfs_readdir(struct vop_readdir_args *ap)
 {
 	struct vnode *vp = ap->a_vp;
 	struct uio *uio = ap->a_uio;
-	int error;
 
 	if (vp->v_type != VDIR)
 		return (EPERM);
@@ -758,8 +757,7 @@ smbfs_readdir(struct vop_readdir_args *ap)
 		return (EOPNOTSUPP);
 	}
 #endif
-	error = smbfs_readvnode(vp, uio, ap->a_cred);
-	return error;
+	return (smbfs_readvnode(vp, uio, ap->a_cred, ap->a_eofflag));
 }
 
 /* ARGSUSED */