fix locking issues uncovered by LOCKDEBUG, reorganize code a bit so that
even the initial directory notify request is sent by smbkq thread problems found during LOCKDEBUG hunt, adresses PR kern/21067 by Martin Husemann
This commit is contained in:
parent
dfc728f814
commit
3068339e18
@ -1,4 +1,4 @@
|
|||||||
/* $NetBSD: smbfs_kq.c,v 1.3 2003/04/07 12:04:15 jdolecek Exp $ */
|
/* $NetBSD: smbfs_kq.c,v 1.4 2003/04/08 18:16:01 jdolecek Exp $ */
|
||||||
|
|
||||||
/*-
|
/*-
|
||||||
* Copyright (c) 2003 The NetBSD Foundation, Inc.
|
* Copyright (c) 2003 The NetBSD Foundation, Inc.
|
||||||
@ -37,7 +37,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include <sys/cdefs.h>
|
#include <sys/cdefs.h>
|
||||||
__KERNEL_RCSID(0, "$NetBSD: smbfs_kq.c,v 1.3 2003/04/07 12:04:15 jdolecek Exp $");
|
__KERNEL_RCSID(0, "$NetBSD: smbfs_kq.c,v 1.4 2003/04/08 18:16:01 jdolecek Exp $");
|
||||||
|
|
||||||
#include <sys/param.h>
|
#include <sys/param.h>
|
||||||
#include <sys/systm.h>
|
#include <sys/systm.h>
|
||||||
@ -131,14 +131,13 @@ smbfs_kqpoll(void *arg)
|
|||||||
{
|
{
|
||||||
struct kevq *ke;
|
struct kevq *ke;
|
||||||
struct vattr attr;
|
struct vattr attr;
|
||||||
int error;
|
int error=0;
|
||||||
struct proc *p = smbkqp;
|
struct proc *p = smbkqp;
|
||||||
u_quad_t osize;
|
u_quad_t osize;
|
||||||
int needwake;
|
int needwake;
|
||||||
|
|
||||||
|
simple_lock(&smbkq_lock);
|
||||||
for(;;) {
|
for(;;) {
|
||||||
simple_lock(&smbkq_lock);
|
|
||||||
|
|
||||||
/* check all entries on poll list for changes */
|
/* check all entries on poll list for changes */
|
||||||
SLIST_FOREACH(ke, &kplist, k_link) {
|
SLIST_FOREACH(ke, &kplist, k_link) {
|
||||||
/* skip if still in attrcache */
|
/* skip if still in attrcache */
|
||||||
@ -197,7 +196,6 @@ smbfs_kqpoll(void *arg)
|
|||||||
/* Exit if there are no more kevents to watch for */
|
/* Exit if there are no more kevents to watch for */
|
||||||
if (kevs == 0) {
|
if (kevs == 0) {
|
||||||
smbkqp = NULL;
|
smbkqp = NULL;
|
||||||
simple_unlock(&smbkq_lock);
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -205,8 +203,11 @@ smbfs_kqpoll(void *arg)
|
|||||||
needwake = !SLIST_EMPTY(&kplist);
|
needwake = !SLIST_EMPTY(&kplist);
|
||||||
|
|
||||||
/* wait a while before checking for changes again */
|
/* wait a while before checking for changes again */
|
||||||
error = ltsleep(smbkqp, PSOCK, "smbkqidl",
|
if (SLIST_EMPTY(&kdnlist)) {
|
||||||
needwake ? (SMBFS_ATTRTIMO * hz / 2) : 0, &smbkq_lock);
|
error = ltsleep(smbkqp, PSOCK, "smbkqidl",
|
||||||
|
needwake ? (SMBFS_ATTRTIMO * hz / 2) : 0,
|
||||||
|
&smbkq_lock);
|
||||||
|
}
|
||||||
|
|
||||||
if (!error) {
|
if (!error) {
|
||||||
/* woken up, check if any pending notifications */
|
/* woken up, check if any pending notifications */
|
||||||
@ -219,6 +220,15 @@ smbfs_kqpoll(void *arg)
|
|||||||
SLIST_NEXT(ke, k_link) = NULL;
|
SLIST_NEXT(ke, k_link) = NULL;
|
||||||
splx(s);
|
splx(s);
|
||||||
|
|
||||||
|
/* drop lock while processing */
|
||||||
|
simple_unlock(&smbkq_lock);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Skip fetch if not yet setup.
|
||||||
|
*/
|
||||||
|
if (__predict_false(ke->rq == NULL))
|
||||||
|
goto notifyrq;
|
||||||
|
|
||||||
error = smbfs_smb_nt_dirnotify_fetch(ke->rq,
|
error = smbfs_smb_nt_dirnotify_fetch(ke->rq,
|
||||||
&hint);
|
&hint);
|
||||||
ke->rq = NULL; /* rq deallocated by now */
|
ke->rq = NULL; /* rq deallocated by now */
|
||||||
@ -234,14 +244,19 @@ smbfs_kqpoll(void *arg)
|
|||||||
|
|
||||||
VN_KNOTE(ke->vp, hint);
|
VN_KNOTE(ke->vp, hint);
|
||||||
|
|
||||||
|
notifyrq:
|
||||||
/* reissue the notify request */
|
/* reissue the notify request */
|
||||||
(void) smbfs_smb_nt_dirnotify_setup(
|
(void) smbfs_smb_nt_dirnotify_setup(
|
||||||
VTOSMB(ke->vp),
|
VTOSMB(ke->vp),
|
||||||
&ke->rq, &smbkq_scred,
|
&ke->rq, &smbkq_scred,
|
||||||
smbfskq_dirnotify, ke);
|
smbfskq_dirnotify, ke);
|
||||||
|
|
||||||
|
/* reacquire the lock */
|
||||||
|
simple_lock(&smbkq_lock);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
simple_unlock(&smbkq_lock);
|
||||||
|
|
||||||
kthread_exit(0);
|
kthread_exit(0);
|
||||||
}
|
}
|
||||||
@ -450,6 +465,7 @@ smbfs_kqfilter(void *v)
|
|||||||
FREE(ken, M_KEVENT); /* dispose, don't need */
|
FREE(ken, M_KEVENT); /* dispose, don't need */
|
||||||
} else {
|
} else {
|
||||||
/* need a new one */
|
/* need a new one */
|
||||||
|
memset(ken, 0, sizeof(*ken));
|
||||||
ke = ken;
|
ke = ken;
|
||||||
ke->vp = vp;
|
ke->vp = vp;
|
||||||
ke->usecount = 1;
|
ke->usecount = 1;
|
||||||
@ -459,16 +475,16 @@ smbfs_kqfilter(void *v)
|
|||||||
ke->onlink = attr.va_nlink;
|
ke->onlink = attr.va_nlink;
|
||||||
|
|
||||||
if (dnot) {
|
if (dnot) {
|
||||||
/* If directory notify, queue request for execution */
|
int s;
|
||||||
SLIST_NEXT(ke, k_link) = NULL;
|
|
||||||
|
|
||||||
error = smbfs_smb_nt_dirnotify_setup(VTOSMB(vp),
|
/*
|
||||||
&ke->rq, &smbkq_scred, smbfskq_dirnotify, ke);
|
* Add kevent to list of 'need attend' kevnets.
|
||||||
if (error) {
|
* The handler will pick it up and setup request
|
||||||
kevs--;
|
* appropriately.
|
||||||
FREE(ke, M_KEVENT);
|
*/
|
||||||
return (error);
|
s = splnet();
|
||||||
}
|
SLIST_INSERT_HEAD(&kdnlist, ke, k_link);
|
||||||
|
splx(s);
|
||||||
dnot_num++;
|
dnot_num++;
|
||||||
} else {
|
} else {
|
||||||
/* add to poll list */
|
/* add to poll list */
|
||||||
|
Loading…
Reference in New Issue
Block a user