Module Name: src
Committed By: christos
Date: Thu Aug 24 19:51:24 UTC 2023
Modified Files:
src/sys/compat/linux/common: linux_inotify.c
Log Message:
fix a locking bug (Theodore Preduta)
To generate a diff of this commit:
cvs rdiff -u -r1.4 -r1.5 src/sys/compat/linux/common/linux_inotify.c
Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.
Modified files:
Index: src/sys/compat/linux/common/linux_inotify.c
diff -u src/sys/compat/linux/common/linux_inotify.c:1.4 src/sys/compat/linux/common/linux_inotify.c:1.5
--- src/sys/compat/linux/common/linux_inotify.c:1.4 Wed Aug 23 15:17:59 2023
+++ src/sys/compat/linux/common/linux_inotify.c Thu Aug 24 15:51:24 2023
@@ -1,4 +1,4 @@
-/* $NetBSD: linux_inotify.c,v 1.4 2023/08/23 19:17:59 christos Exp $ */
+/* $NetBSD: linux_inotify.c,v 1.5 2023/08/24 19:51:24 christos Exp $ */
/*-
* Copyright (c) 2023 The NetBSD Foundation, Inc.
@@ -29,7 +29,7 @@
* POSSIBILITY OF SUCH DAMAGE.
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: linux_inotify.c,v 1.4 2023/08/23 19:17:59 christos Exp $");
+__KERNEL_RCSID(0, "$NetBSD: linux_inotify.c,v 1.5 2023/08/24 19:51:24 christos Exp $");
#include <sys/param.h>
#include <sys/types.h>
@@ -790,9 +790,18 @@ inotify_readdir(file_t *fp, struct diren
/* XXX: should pass whether to lock or not */
if (needs_lock)
vn_lock(vp, LK_SHARED | LK_RETRY);
+ else
+ /*
+ * XXX We need to temprarily drop v_interlock because
+ * it may be temporarily acquired by biowait().
+ */
+ mutex_exit(vp->v_interlock);
+ KASSERT(!mutex_owned(vp->v_interlock));
error = VOP_READDIR(vp, &uio, fp->f_cred, &eofflag, NULL, NULL);
if (needs_lock)
VOP_UNLOCK(vp);
+ else
+ mutex_enter(vp->v_interlock);
mutex_enter(&fp->f_lock);
fp->f_offset = uio.uio_offset;
@@ -1107,7 +1116,7 @@ inotify_filt_event(struct knote *kn, lon
cv_signal(&ifd->ifd_qcv);
mutex_enter(&ifd->ifd_lock);
- selnotify(&ifd->ifd_sel, 0, 0);
+ selnotify(&ifd->ifd_sel, 0, NOTE_LOWAT);
mutex_exit(&ifd->ifd_lock);
} else
DPRINTF(("%s: hint=%lx resulted in 0 inotify events\n",
@@ -1295,14 +1304,17 @@ inotify_read_filt_detach(struct knote *k
static int
inotify_read_filt_event(struct knote *kn, long hint)
{
- int rv;
struct inotifyfd *ifd = ((file_t *)kn->kn_obj)->f_data;
- mutex_enter(&ifd->ifd_qlock);
- rv = (ifd->ifd_qcount > 0);
- mutex_exit(&ifd->ifd_qlock);
+ if (hint != 0) {
+ KASSERT(mutex_owned(&ifd->ifd_lock));
+ KASSERT(mutex_owned(&ifd->ifd_qlock));
+ KASSERT(hint == NOTE_LOWAT);
+
+ kn->kn_data = ifd->ifd_qcount;
+ }
- return rv;
+ return kn->kn_data > 0;
}
/*