summaryrefslogtreecommitdiffstats
path: root/sys/kern/vfs_aio.c
diff options
context:
space:
mode:
authoralc <alc@FreeBSD.org>2002-03-31 20:17:56 +0000
committeralc <alc@FreeBSD.org>2002-03-31 20:17:56 +0000
commit6985f3b63c2fc767462eeb1285d32b2e0c0f82b0 (patch)
treef9798db9f5893a9e47d5080b55e681a5e4812856 /sys/kern/vfs_aio.c
parent0350a837b543daceec97c9d824d901a41b9bb533 (diff)
downloadFreeBSD-src-6985f3b63c2fc767462eeb1285d32b2e0c0f82b0.zip
FreeBSD-src-6985f3b63c2fc767462eeb1285d32b2e0c0f82b0.tar.gz
Keep the reference to the file acquired in _aio_aqueue() until the operation
completes. The reference is released in aio_free_entry(). Submitted by: tegge
Diffstat (limited to 'sys/kern/vfs_aio.c')
-rw-r--r--sys/kern/vfs_aio.c10
1 files changed, 7 insertions, 3 deletions
diff --git a/sys/kern/vfs_aio.c b/sys/kern/vfs_aio.c
index 56d3a1e..7f11bea 100644
--- a/sys/kern/vfs_aio.c
+++ b/sys/kern/vfs_aio.c
@@ -510,6 +510,7 @@ aio_free_entry(struct aiocblist *aiocbe)
}
aiocbe->jobstate = JOBST_NULL;
untimeout(process_signal, aiocbe, aiocbe->timeouthandle);
+ fdrop(aiocbe->fd_file, curthread);
uma_zfree(aiocb_zone, aiocbe);
return 0;
}
@@ -1390,8 +1391,10 @@ _aio_aqueue(struct thread *td, struct aiocb *job, struct aio_liojob *lj, int typ
suword(&job->_aiocb_private.error, EBADF);
return EBADF;
}
+ fhold(fp);
if (aiocbe->uaiocb.aio_offset == -1LL) {
+ fdrop(fp, td);
uma_zfree(aiocb_zone, aiocbe);
if (type == 0)
suword(&job->_aiocb_private.error, EINVAL);
@@ -1400,6 +1403,7 @@ _aio_aqueue(struct thread *td, struct aiocb *job, struct aio_liojob *lj, int typ
error = suword(&job->_aiocb_private.kernelinfo, jobrefid);
if (error) {
+ fdrop(fp, td);
uma_zfree(aiocb_zone, aiocbe);
if (type == 0)
suword(&job->_aiocb_private.error, EINVAL);
@@ -1413,6 +1417,7 @@ _aio_aqueue(struct thread *td, struct aiocb *job, struct aio_liojob *lj, int typ
jobrefid++;
if (opcode == LIO_NOP) {
+ fdrop(fp, td);
uma_zfree(aiocb_zone, aiocbe);
if (type == 0) {
suword(&job->_aiocb_private.error, 0);
@@ -1423,6 +1428,7 @@ _aio_aqueue(struct thread *td, struct aiocb *job, struct aio_liojob *lj, int typ
}
if ((opcode != LIO_READ) && (opcode != LIO_WRITE)) {
+ fdrop(fp, td);
uma_zfree(aiocb_zone, aiocbe);
if (type == 0) {
suword(&job->_aiocb_private.status, 0);
@@ -1431,8 +1437,6 @@ _aio_aqueue(struct thread *td, struct aiocb *job, struct aio_liojob *lj, int typ
return EINVAL;
}
- fhold(fp);
-
if (aiocbe->uaiocb.aio_sigevent.sigev_notify == SIGEV_KEVENT) {
kev.ident = aiocbe->uaiocb.aio_sigevent.sigev_notify_kqueue;
kev.udata = aiocbe->uaiocb.aio_sigevent.sigev_value.sigval_ptr;
@@ -1467,6 +1471,7 @@ _aio_aqueue(struct thread *td, struct aiocb *job, struct aio_liojob *lj, int typ
error = kqueue_register(kq, &kev, td);
aqueue_fail:
if (error) {
+ fdrop(fp, td);
uma_zfree(aiocb_zone, aiocbe);
if (type == 0)
suword(&job->_aiocb_private.error, error);
@@ -1562,7 +1567,6 @@ retryproc:
}
splx(s);
done:
- fdrop(fp, td);
return error;
}
OpenPOWER on IntegriCloud