git: e1d9d8fe64ee - stable/13 - Add descrip_check_write_mp() helper

From: Konstantin Belousov <kib_at_FreeBSD.org>
Date: Fri, 20 Jan 2023 03:23:49 UTC
The branch stable/13 has been updated by kib:

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

commit e1d9d8fe64ee94f78d679235bb76b2a01068b4b2
Author:     Konstantin Belousov <kib@FreeBSD.org>
AuthorDate: 2022-12-28 18:13:01 +0000
Commit:     Konstantin Belousov <kib@FreeBSD.org>
CommitDate: 2023-01-20 03:21:23 +0000

    Add descrip_check_write_mp() helper
    
    Tested by:      pho
    
    (cherry picked from commit 37b9fb169686e867987c8a1a9868f81137b9df2b)
---
 sys/kern/kern_descrip.c | 25 +++++++++++++++++++++++++
 sys/sys/filedesc.h      |  2 ++
 2 files changed, 27 insertions(+)

diff --git a/sys/kern/kern_descrip.c b/sys/kern/kern_descrip.c
index ff999cc82f97..6b2d95d53db0 100644
--- a/sys/kern/kern_descrip.c
+++ b/sys/kern/kern_descrip.c
@@ -4238,6 +4238,31 @@ mountcheckdirs(struct vnode *olddp, struct vnode *newdp)
 		vrele(olddp);
 }
 
+int
+descrip_check_write_mp(struct filedesc *fdp, struct mount *mp)
+{
+	struct file *fp;
+	struct vnode *vp;
+	int error, i, lastfile;
+
+	error = 0;
+	FILEDESC_SLOCK(fdp);
+	lastfile = fdlastfile(fdp);
+	for (i = 0; i <= lastfile; i++) {
+		fp = fdp->fd_ofiles[i].fde_file;
+		if (fp->f_type != DTYPE_VNODE ||
+		    (atomic_load_int(&fp->f_flag) & FWRITE) == 0)
+			continue;
+		vp = fp->f_vnode;
+		if (vp->v_mount == mp) {
+			error = EDEADLK;
+			break;
+		}
+	}
+	FILEDESC_SUNLOCK(fdp);
+	return (error);
+}
+
 struct filedesc_to_leader *
 filedesc_to_leader_alloc(struct filedesc_to_leader *old, struct filedesc *fdp,
     struct proc *leader)
diff --git a/sys/sys/filedesc.h b/sys/sys/filedesc.h
index 345576438c67..5a4b3de33104 100644
--- a/sys/sys/filedesc.h
+++ b/sys/sys/filedesc.h
@@ -214,6 +214,7 @@ enum {
 #define	falloc(td, resultfp, resultfd, flags) \
 	falloc_caps(td, resultfp, resultfd, flags, NULL)
 
+struct mount;
 struct thread;
 
 static __inline void
@@ -230,6 +231,7 @@ void	filecaps_free(struct filecaps *fcaps);
 
 int	closef(struct file *fp, struct thread *td);
 void	closef_nothread(struct file *fp);
+int	descrip_check_write_mp(struct filedesc *fdp, struct mount *mp);
 int	dupfdopen(struct thread *td, struct filedesc *fdp, int dfd, int mode,
 	    int openerror, int *indxp);
 int	falloc_caps(struct thread *td, struct file **resultfp, int *resultfd,