diff options
author | Thordur I. Bjornsson <thib@cvs.openbsd.org> | 2009-08-26 12:08:11 +0000 |
---|---|---|
committer | Thordur I. Bjornsson <thib@cvs.openbsd.org> | 2009-08-26 12:08:11 +0000 |
commit | eeed523198867ebd135391608cc58cb62ed7f6ce (patch) | |
tree | 3e3ecf49a6702ad0a358b9b9d27eb1500bccb39d /sys/nfs | |
parent | ee5b22f6fe46ed87deb590c37599fd03064be129 (diff) |
make sure that an aiod has been removed from the nfs_aiods_idle list
before inserting it back into the list.
crashes debugged with help from deraadt@ who also tested this fix.
Diffstat (limited to 'sys/nfs')
-rw-r--r-- | sys/nfs/nfs_aiod.c | 8 | ||||
-rw-r--r-- | sys/nfs/nfs_bio.c | 5 | ||||
-rw-r--r-- | sys/nfs/nfsnode.h | 3 |
3 files changed, 11 insertions, 5 deletions
diff --git a/sys/nfs/nfs_aiod.c b/sys/nfs/nfs_aiod.c index a3425163ee0..3c0b269182d 100644 --- a/sys/nfs/nfs_aiod.c +++ b/sys/nfs/nfs_aiod.c @@ -1,4 +1,4 @@ -/* $OpenBSD: nfs_aiod.c,v 1.1 2009/08/20 15:04:24 thib Exp $ */ +/* $OpenBSD: nfs_aiod.c,v 1.2 2009/08/26 12:08:10 thib Exp $ */ /* * Copyright (c) 1989, 1993 * The Regents of the University of California. All rights reserved. @@ -82,6 +82,7 @@ nfs_aiod(void *arg) aiod = malloc(sizeof(*aiod), M_TEMP, M_WAITOK|M_ZERO); mtx_enter(&nfs_aiodl_mtx); LIST_INSERT_HEAD(&nfs_aiods_all, aiod, nad_all); + LIST_INSERT_HEAD(&nfs_aiods_idle, aiod, nad_idle); mtx_leave(&nfs_aiodl_mtx); nfs_numaiods++; @@ -102,7 +103,10 @@ nfs_aiod(void *arg) loop: /* Loop around until SIGKILL */ mtx_enter(&nfs_aiodl_mtx); - LIST_INSERT_HEAD(&nfs_aiods_idle, aiod, nad_idle); + if (aiod->nad_worked) { + LIST_INSERT_HEAD(&nfs_aiods_idle, aiod, nad_idle); + aiod->nad_worked = 0; + } mtx_leave(&nfs_aiodl_mtx); while (1) { diff --git a/sys/nfs/nfs_bio.c b/sys/nfs/nfs_bio.c index 6b17f779e6d..7350481ea41 100644 --- a/sys/nfs/nfs_bio.c +++ b/sys/nfs/nfs_bio.c @@ -1,4 +1,4 @@ -/* $OpenBSD: nfs_bio.c,v 1.63 2009/08/20 15:04:24 thib Exp $ */ +/* $OpenBSD: nfs_bio.c,v 1.64 2009/08/26 12:08:10 thib Exp $ */ /* $NetBSD: nfs_bio.c,v 1.25.4.2 1996/07/08 20:47:04 jtc Exp $ */ /* @@ -517,10 +517,11 @@ nfs_asyncio(struct buf *bp) aiod = LIST_FIRST(&nfs_aiods_idle); if (aiod) { /* - * Found an avilable aiod, wake it up and send + * Found an available aiod, wake it up and send * it to work on this mount. */ LIST_REMOVE(aiod, nad_idle); + aiod->nad_worked = 1; mtx_leave(&nfs_aiodl_mtx); gotone = 1; KASSERT(aiod->nad_mnt == NULL); diff --git a/sys/nfs/nfsnode.h b/sys/nfs/nfsnode.h index 6f95d808bb0..890323078f1 100644 --- a/sys/nfs/nfsnode.h +++ b/sys/nfs/nfsnode.h @@ -1,4 +1,4 @@ -/* $OpenBSD: nfsnode.h,v 1.35 2009/08/20 15:04:24 thib Exp $ */ +/* $OpenBSD: nfsnode.h,v 1.36 2009/08/26 12:08:10 thib Exp $ */ /* $NetBSD: nfsnode.h,v 1.16 1996/02/18 11:54:04 fvdl Exp $ */ /* @@ -143,6 +143,7 @@ struct nfs_aiod { LIST_ENTRY(nfs_aiod) nad_idle; struct nfsmount *nad_mnt; int nad_exiting; + int nad_worked; /* Was removed from idle list. */ }; LIST_HEAD(nfs_aiodhead, nfs_aiod); |