diff options
author | peadar <peadar@FreeBSD.org> | 2005-09-29 10:37:20 +0000 |
---|---|---|
committer | peadar <peadar@FreeBSD.org> | 2005-09-29 10:37:20 +0000 |
commit | 05494531ef17f0a050b22fcede40c159b13224de (patch) | |
tree | 1c52f74d93f11050415978da5b737289c54e4a26 /sys/kern | |
parent | 2c9137ee39a7e893eb2fb8ede914e2149ba7c93d (diff) | |
download | FreeBSD-src-05494531ef17f0a050b22fcede40c159b13224de.zip FreeBSD-src-05494531ef17f0a050b22fcede40c159b13224de.tar.gz |
Close a race in biodone(), whereby the bio_done field of the passed
bio may have been freed and reassigned by the wakeup before being
tested after releasing the bdonelock.
There's a non-zero chance this is the cause of a few of the crashes
knocking around with biodone() sitting in the stack backtrace.
Reviewed By: phk@
Diffstat (limited to 'sys/kern')
-rw-r--r-- | sys/kern/vfs_bio.c | 8 |
1 files changed, 5 insertions, 3 deletions
diff --git a/sys/kern/vfs_bio.c b/sys/kern/vfs_bio.c index 66cfa1e..80e4d10 100644 --- a/sys/kern/vfs_bio.c +++ b/sys/kern/vfs_bio.c @@ -2882,14 +2882,16 @@ allocbuf(struct buf *bp, int size) void biodone(struct bio *bp) { + void (*done)(struct bio *); mtx_lock(&bdonelock); bp->bio_flags |= BIO_DONE; - if (bp->bio_done == NULL) + done = bp->bio_done; + if (done == NULL) wakeup(bp); mtx_unlock(&bdonelock); - if (bp->bio_done != NULL) - bp->bio_done(bp); + if (done != NULL) + done(bp); } /* |