From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from mailman by lists.gnu.org with tmda-scanned (Exim 4.43) id 1LDedN-0001W9-M1 for qemu-devel@nongnu.org; Fri, 19 Dec 2008 07:39:13 -0500 Received: from exim by lists.gnu.org with spam-scanned (Exim 4.43) id 1LDedM-0001VR-AP for qemu-devel@nongnu.org; Fri, 19 Dec 2008 07:39:13 -0500 Received: from [199.232.76.173] (port=50935 helo=monty-python.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1LDedM-0001VO-0L for qemu-devel@nongnu.org; Fri, 19 Dec 2008 07:39:12 -0500 Received: from gecko.sbs.de ([194.138.37.40]:20464) by monty-python.gnu.org with esmtps (TLS-1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.60) (envelope-from ) id 1LDedL-0003A6-Fp for qemu-devel@nongnu.org; Fri, 19 Dec 2008 07:39:11 -0500 Message-ID: <494B95CC.8070008@siemens.com> Date: Fri, 19 Dec 2008 13:38:36 +0100 From: Jan Kiszka MIME-Version: 1.0 Content-Type: text/plain; charset=ISO-8859-15 Content-Transfer-Encoding: 7bit Subject: [Qemu-devel] [PATCH] Fix race in POSIX AIO emulation Reply-To: qemu-devel@nongnu.org List-Id: qemu-devel.nongnu.org List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: Anthony Liguori Cc: qemu-devel@nongnu.org When we cancel an AIO request that is already being processed by aio_thread, qemu_paio_cancel should return QEMU_PAIO_NOTCANCELED as long as aio_thread isn't done with this request. But as the latter currently updates aiocb->ret after every block of the request, we may report QEMU_PAIO_ALLDONE too early. Futhermore, in case some zero-length request should have been queued, aiocb->ret is never set to != -EINPROGRESS and callers like raw_aio_cancel could get stuck in an endless loop. Fix those issues by updating aiocb->ret _after_ the request has been fully processed. This also simplifies the locking. Signed-off-by: Jan Kiszka --- posix-aio-compat.c | 9 ++------- 1 files changed, 2 insertions(+), 7 deletions(-) diff --git a/posix-aio-compat.c b/posix-aio-compat.c index 92ec234..c919e3b 100644 --- a/posix-aio-compat.c +++ b/posix-aio-compat.c @@ -81,21 +81,16 @@ static void *aio_thread(void *unused) if (len == -1 && errno == EINTR) continue; else if (len == -1) { - pthread_mutex_lock(&lock); - aiocb->ret = -errno; - pthread_mutex_unlock(&lock); + offset = -errno; break; } else if (len == 0) break; offset += len; - - pthread_mutex_lock(&lock); - aiocb->ret = offset; - pthread_mutex_unlock(&lock); } pthread_mutex_lock(&lock); + aiocb->ret = offset; idle_threads++; pthread_mutex_unlock(&lock);