aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKonstantin Belousov <kib@FreeBSD.org>2022-12-28 18:13:01 +0000
committerKonstantin Belousov <kib@FreeBSD.org>2023-01-20 03:21:23 +0000
commite1d9d8fe64ee94f78d679235bb76b2a01068b4b2 (patch)
tree30f1c6140f426cb5f25be254fa8fe8bfe31575f9
parent1610f04c9daceb5b4f2849e48d0021ecc975bb60 (diff)
Add descrip_check_write_mp() helper
Tested by: pho (cherry picked from commit 37b9fb169686e867987c8a1a9868f81137b9df2b)
-rw-r--r--sys/kern/kern_descrip.c25
-rw-r--r--sys/sys/filedesc.h2
2 files changed, 27 insertions, 0 deletions
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,