Page MenuHomeFreeBSD

D37896.id114620.diff
No OneTemporary

D37896.id114620.diff

diff --git a/sys/kern/kern_descrip.c b/sys/kern/kern_descrip.c
--- a/sys/kern/kern_descrip.c
+++ b/sys/kern/kern_descrip.c
@@ -4172,6 +4172,29 @@
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
--- a/sys/sys/filedesc.h
+++ b/sys/sys/filedesc.h
@@ -225,6 +225,7 @@
#define falloc(td, resultfp, resultfd, flags) \
falloc_caps(td, resultfp, resultfd, flags, NULL)
+struct mount;
struct thread;
static __inline void
@@ -241,6 +242,7 @@
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,
diff --git a/sys/ufs/ffs/ffs_suspend.c b/sys/ufs/ffs/ffs_suspend.c
--- a/sys/ufs/ffs/ffs_suspend.c
+++ b/sys/ufs/ffs/ffs_suspend.c
@@ -33,15 +33,15 @@
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
-#include <sys/param.h>
#include <sys/systm.h>
#include <sys/buf.h>
-#include <sys/ioccom.h>
-#include <sys/mount.h>
-#include <sys/vnode.h>
#include <sys/conf.h>
+#include <sys/filedesc.h>
+#include <sys/ioccom.h>
#include <sys/jail.h>
+#include <sys/mount.h>
#include <sys/sx.h>
+#include <sys/vnode.h>
#include <security/mac/mac_framework.h>
@@ -303,6 +303,16 @@
vfs_rel(mp);
if (error != 0)
break;
+
+ /*
+ * XXXKIB: might consider to singlethread curproc so
+ * that the check is not racy.
+ */
+ error = curproc->p_numthreads > 1 ? EDEADLK :
+ descrip_check_write_mp(curproc->p_fd, mp);
+ if (error != 0)
+ break;
+
error = ffs_susp_suspend(mp);
if (error != 0) {
vfs_unbusy(mp);

File Metadata

Mime Type
text/plain
Expires
Wed, Aug 26, 10:32 AM (36 m, 41 s)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
37287653
Default Alt Text
D37896.id114620.diff (2 KB)

Event Timeline