Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S932836AbcCKQfm (ORCPT ); Fri, 11 Mar 2016 11:35:42 -0500 Received: from mail-oi0-f42.google.com ([209.85.218.42]:33636 "EHLO mail-oi0-f42.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S932687AbcCKQfj (ORCPT ); Fri, 11 Mar 2016 11:35:39 -0500 From: Seth Forshee To: fuse-devel@lists.sourceforge.net Cc: Miklos Szeredi , m.loschwitz@syseleven.de, robert@quobyte.com, seth.forshee@canonical.com, linux-kernel@vger.kernel.org Subject: [PATCH 0/2] Fix async io races Date: Fri, 11 Mar 2016 10:35:32 -0600 Message-Id: <1457714135-50289-1-git-send-email-seth.forshee@canonical.com> X-Mailer: git-send-email 1.9.1 Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Length: 2151 Lines: 44 These patches are fixes for the problems reported at https://sourceforge.net/p/fuse/mailman/message/34537139/. The first patch is one of those that Robert posted on that thread, and the second is a different patch that Robert and I agree represents a more robust solution to the race. The first race is that a is_sync_kiocb() is called on an iocb that could have been freed if async io has already completed. The fix in this case is simple and obvious: cache the result before starting io. In the second case aio completion results in waking a waiting task followed by unlocking the fuse_io_priv object. The waiting task will free that object once awoken though, so it's possible for the object to be freed before spin_unlock() is called. The simple fix is to move the unlock to before the wake, but really this problem suggests a more fundamental problem in the lifecycle of fuse_io_priv objects. The request count in this object is serving two purposes, to count outstanding aio requests to the fuse server and to serve as a reference count in the object. For synchronous io these roles come into conflict. The task which submits io must wait for all requests to the fuse server to finish and then retrieve the result of the operation from the fuse_io_priv object, yet it will not be woken until the outstanding request count reaches 0. This means the task must release its reference to the object before waiting, which leads to a somewhat confusing set of rules for when it is safe to free the object. This becomes much more straightforward if a separate reference count is maintained for fuse_io_priv objects. Then the waiting task can hold a reference while waiting, and there is no ambiguity about whether or not it is safe to free an object. The second patch implements this solution. Thanks, Seth Robert Doebbelin (1): fuse: do not use iocb after it may have been freed Seth Forshee (1): fuse: Add reference counting for fuse_io_priv fs/fuse/cuse.c | 12 ++++++++++-- fs/fuse/file.c | 47 +++++++++++++++++++++++++++++++++++++---------- fs/fuse/fuse_i.h | 15 +++++++++++++++ 3 files changed, 62 insertions(+), 12 deletions(-)