aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--sys/kern/kern_descrip.c23
-rw-r--r--sys/sys/filedesc.h2
2 files changed, 25 insertions, 0 deletions
diff --git a/sys/kern/kern_descrip.c b/sys/kern/kern_descrip.c
index 63a7f8b2a6d7..0be59e930dd4 100644
--- a/sys/kern/kern_descrip.c
+++ b/sys/kern/kern_descrip.c
@@ -4172,6 +4172,29 @@ 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;
+
+ error = 0;
+ FILEDESC_SLOCK(fdp);
+ FILEDESC_FOREACH_FP(fdp, i, fp) {
+ 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 52bd3c97a9ac..ffea8d7e0195 100644
--- a/sys/sys/filedesc.h
+++ b/sys/sys/filedesc.h
@@ -225,6 +225,7 @@ enum {
#define falloc(td, resultfp, resultfd, flags) \
falloc_caps(td, resultfp, resultfd, flags, NULL)
+struct mount;
struct thread;
static __inline void
@@ -241,6 +242,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,