git: c6487446d7e9 - main - getdirentries: return ENOENT for unlinked but still open directory.

From: Dmitry Chagin <dchagin_at_FreeBSD.org>
Date: Mon, 11 Apr 2022 20:30:52 UTC
The branch main has been updated by dchagin:

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

commit c6487446d7e99537551d2e51a2f6c6569fcb89fc
Author:     Dmitry Chagin <dchagin@FreeBSD.org>
AuthorDate: 2022-04-11 20:30:16 +0000
Commit:     Dmitry Chagin <dchagin@FreeBSD.org>
CommitDate: 2022-04-11 20:30:16 +0000

    getdirentries: return ENOENT for unlinked but still open directory.
    
    To be more compatible to IEEE Std 1003.1-2008 (“POSIX.1”).
    
    Reviewed by:            mjg, Pau Amma (doc)
    Differential revision:  https://reviews.freebsd.org/D34680
    MFC after:              2 weeks
---
 lib/libc/sys/getdirentries.2 | 2 ++
 sys/kern/vfs_subr.c          | 1 +
 sys/kern/vfs_syscalls.c      | 4 ++++
 sys/sys/vnode.h              | 2 +-
 4 files changed, 8 insertions(+), 1 deletion(-)

diff --git a/lib/libc/sys/getdirentries.2 b/lib/libc/sys/getdirentries.2
index 4185fb84f0f9..76fe18bf6edb 100644
--- a/lib/libc/sys/getdirentries.2
+++ b/lib/libc/sys/getdirentries.2
@@ -193,6 +193,8 @@ An
 error occurred while reading from or writing to the file system.
 .It Bq Er EINTEGRITY
 Corrupted data was detected while reading from the file system.
+.It Bq Er ENOENT
+Directory unlinked but still open.
 .El
 .Sh SEE ALSO
 .Xr lseek 2 ,
diff --git a/sys/kern/vfs_subr.c b/sys/kern/vfs_subr.c
index bbb429085a24..a6344e139502 100644
--- a/sys/kern/vfs_subr.c
+++ b/sys/kern/vfs_subr.c
@@ -5980,6 +5980,7 @@ vop_rmdir_post(void *ap, int rc)
 	vn_seqc_write_end(dvp);
 	vn_seqc_write_end(vp);
 	if (!rc) {
+		vp->v_vflag |= VV_UNLINKED;
 		VFS_KNOTE_LOCKED(dvp, NOTE_WRITE | NOTE_LINK);
 		VFS_KNOTE_LOCKED(vp, NOTE_DELETE);
 	}
diff --git a/sys/kern/vfs_syscalls.c b/sys/kern/vfs_syscalls.c
index 87bf0a9d866b..77a9b9c25290 100644
--- a/sys/kern/vfs_syscalls.c
+++ b/sys/kern/vfs_syscalls.c
@@ -4195,6 +4195,10 @@ unionread:
 		error = EINVAL;
 		goto fail;
 	}
+	if (__predict_false((vp->v_vflag & VV_UNLINKED) != 0)) {
+		error = ENOENT;
+		goto fail;
+	}
 	aiov.iov_base = buf;
 	aiov.iov_len = count;
 	auio.uio_iov = &aiov;
diff --git a/sys/sys/vnode.h b/sys/sys/vnode.h
index 0ff7501837c7..ed292835c12f 100644
--- a/sys/sys/vnode.h
+++ b/sys/sys/vnode.h
@@ -270,7 +270,7 @@ struct xvnode {
 #define	VV_COPYONWRITE	0x0040	/* vnode is doing copy-on-write */
 #define	VV_SYSTEM	0x0080	/* vnode being used by kernel */
 #define	VV_PROCDEP	0x0100	/* vnode is process dependent */
-/* UNUSED		0x0200	*/
+#define	VV_UNLINKED	0x0200	/* unlinked but stil open directory */
 #define	VV_DELETED	0x0400	/* should be removed */
 #define	VV_MD		0x0800	/* vnode backs the md device */
 #define	VV_FORCEINSMQ	0x1000	/* force the insmntque to succeed */