Received: by 2002:a05:6a10:22f:0:0:0:0 with SMTP id 15csp304391pxk; Thu, 24 Sep 2020 06:16:00 -0700 (PDT) X-Google-Smtp-Source: ABdhPJzMZrhyYXfA42hGtlxzJ3Iq3K2uH3520inpjQEBunEUsTLQmS6fLufp+NMid0BnL6mXsT1Y X-Received: by 2002:a17:906:850e:: with SMTP id i14mr992274ejx.168.1600953360373; Thu, 24 Sep 2020 06:16:00 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1600953360; cv=none; d=google.com; s=arc-20160816; b=eiK8oIwY8o2gkINTX9n3iMyOXqpcgLQunTjObXd9OfdcUERudZa6yuPbzWbKN51Jqd kBAW7h4Q/UW3YtZBEBZyk33xTiBs8d4EUt3WIuPWImHWD+82M4cgWkTrNIfVzpnYdwhC IaVra6zm757iNC4oIRSxSwPlqW40cJTaULfdEzZK6yccY8W0HSGDPz04Ph/8A9aI2IDm jnT+e0aVFwIt3QdFr7Wqz4Zzx7R8fAl6xS7bclABYnxLRvD1urFXVsWgnLqdOKsAsfYh NwP5ClmkYBq+hA2eBGX9F7KStLzrG09EfE/EpGp23gGSy2gvZLvzGoR7VwUUbEjBuaw5 0wEQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:content-transfer-encoding:mime-version :references:in-reply-to:message-id:date:subject:cc:to:from :dkim-signature; bh=SnFurKpeBkbwLq0KOJ5lvNPVyL4t0UDoYrGfHs7nv0A=; b=RFL/z7LxCxjU76fVZXkBWR3tKOSA4ymvCZMDDdvJxV9Wg/OVutjHR9Ahk/Mda2HNw8 72fpPLc7EanuuQ6Boevzus76NxgSXOFuq4BVYpe2KXFON/h5Zwno+G9gpBXTwTjngfzB XLyqwtcLB3Bjzxd2aqgjzkRCkU7e+Sk9qJ28UFnyipviCA8lkxZI17VG2/oU5zxH9OAc p5ZkFTH8I9jhKKR3wRtew3GVRs2Z8CY53dHfmUqdyub7iQykf8mHM/SQbslAXyvCX0Ia HqytPQDwFpRPY8gwD18bCcelRkjLew/vzvz1985B4i5pdqUbGiQJICqmSDrGFJ4bJyqr p81A== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@android.com header.s=20161025 header.b=c49kIoCN; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=REJECT sp=REJECT dis=NONE) header.from=android.com Return-Path: Received: from vger.kernel.org (vger.kernel.org. [23.128.96.18]) by mx.google.com with ESMTP id dp1si2353691ejc.307.2020.09.24.06.15.36; Thu, 24 Sep 2020 06:16:00 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) client-ip=23.128.96.18; Authentication-Results: mx.google.com; dkim=pass header.i=@android.com header.s=20161025 header.b=c49kIoCN; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=REJECT sp=REJECT dis=NONE) header.from=android.com Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728020AbgIXNNn (ORCPT + 99 others); Thu, 24 Sep 2020 09:13:43 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:46162 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1727984AbgIXNN2 (ORCPT ); Thu, 24 Sep 2020 09:13:28 -0400 Received: from mail-wr1-x444.google.com (mail-wr1-x444.google.com [IPv6:2a00:1450:4864:20::444]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id C79F7C0613D5 for ; Thu, 24 Sep 2020 06:13:27 -0700 (PDT) Received: by mail-wr1-x444.google.com with SMTP id z1so3787011wrt.3 for ; Thu, 24 Sep 2020 06:13:27 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=android.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=SnFurKpeBkbwLq0KOJ5lvNPVyL4t0UDoYrGfHs7nv0A=; b=c49kIoCNMCWuGzzxSiHgueczTg5CkgrwLkGuWWq0FAGajSgKan0mFscWOzZVZ+m05d RbXYXA5FxFJCeXX7mCyh/aiJnyvqxapJeon+80154c1bUNnQb82F4gdw7Ej5UktyMO7k rdobOrqsNJFec7D8/br7wA47DdV9NURPNYsPThcpOki9m0thIqLiLbuRY4FgjXMsR04N SgpRRL5PtFgFAYE/gC7RVtUpmBRrctaosbCu9mkSBwDACxmcy70fQW+z6IZaqNo6orLr KL9ZHtgqVaorBff9YMt60zaVL854011zyCBngVeDEpHIO6pUMJdPr0mg9vOQxDHTy24j Fobg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=SnFurKpeBkbwLq0KOJ5lvNPVyL4t0UDoYrGfHs7nv0A=; b=krCxizmL5zs0LdJ7PAzdCVEWYwxWZTCAtjXRwz1F2asNiG7mMAvO7nm6Gu/oKNpxXP Ct3/Iz7GjZXnx7hOVmnUd+Dam8WRAf0/tSyBD3BssB2Mi3fPVbv5mG6dMC9Q0foMcEGH 6W2gUwO2Kua9EdzBDh1PgWjwaKHlhJloooTj1HpoExg0wyPS67ZXeldZgcL6xOYTw6GI LRr9A5iYObHIv7B+TE5oCWdx/ukKG3HqitLk9Q1DHtXlKjzCW/4C12Ce1KeYS5cG5XWc 1YGGQkONVkVFAy849aoxnLqyxCxce2u+gdM7OEunyjFXUBIKmnQFqHpQo8xYU10KHuP/ StSg== X-Gm-Message-State: AOAM533tSdgTdSBaY0VJOkkqK61igkRjSQKPX6jdq33E5Tp7mPuU9mZZ ovpLSZnInlQh9wFp+OXEnVYv2w== X-Received: by 2002:adf:cd0e:: with SMTP id w14mr5608662wrm.0.1600953206542; Thu, 24 Sep 2020 06:13:26 -0700 (PDT) Received: from balsini.lon.corp.google.com ([2a00:79e0:d:210:7220:84ff:fe09:7d5c]) by smtp.gmail.com with ESMTPSA id k22sm3805044wrd.29.2020.09.24.06.13.25 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 24 Sep 2020 06:13:25 -0700 (PDT) From: Alessio Balsini To: Miklos Szeredi Cc: Akilesh Kailash , Amir Goldstein , Antonio SJ Musumeci , David Anderson , Giuseppe Scrivano , Jann Horn , Jens Axboe , Martijn Coenen , Palmer Dabbelt , Paul Lawrence , Stefano Duo , Zimuzo Ezeozue , fuse-devel@lists.sourceforge.net, kernel-team@android.com, linux-fsdevel@vger.kernel.org, linux-kernel@vger.kernel.org Subject: [PATCH V9 4/4] fuse: Handle asynchronous read and write in passthrough Date: Thu, 24 Sep 2020 14:13:18 +0100 Message-Id: <20200924131318.2654747-5-balsini@android.com> X-Mailer: git-send-email 2.28.0.681.g6f77f65b4e-goog In-Reply-To: <20200924131318.2654747-1-balsini@android.com> References: <20200924131318.2654747-1-balsini@android.com> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Extend the passthrough feature by handling asynchronous IO both for read and write operations. When an AIO request is received, if the request targets a FUSE file with the passthrough functionality enabled, a new identical AIO request is created. The new request targets the lower file system file, and gets assigned a special FUSE passthrough AIO completion callback. When the lower file system AIO request is completed, the FUSE passthrough AIO completion callback is executed and propagates the completion signal to the FUSE AIO request by triggering its completion callback as well. Signed-off-by: Alessio Balsini --- fs/fuse/passthrough.c | 64 +++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 62 insertions(+), 2 deletions(-) diff --git a/fs/fuse/passthrough.c b/fs/fuse/passthrough.c index f70c0ef6945b..b7d1a5517ffd 100644 --- a/fs/fuse/passthrough.c +++ b/fs/fuse/passthrough.c @@ -4,6 +4,11 @@ #include +struct fuse_aio_req { + struct kiocb iocb; + struct kiocb *iocb_fuse; +}; + static void fuse_copyattr(struct file *dst_file, struct file *src_file) { struct inode *dst = file_inode(dst_file); @@ -39,6 +44,32 @@ fuse_passthrough_override_creds(const struct file *fuse_filp) return override_creds(fc->creator_cred); } +static void fuse_aio_cleanup_handler(struct fuse_aio_req *aio_req) +{ + struct kiocb *iocb = &aio_req->iocb; + struct kiocb *iocb_fuse = aio_req->iocb_fuse; + + if (iocb->ki_flags & IOCB_WRITE) { + __sb_writers_acquired(file_inode(iocb->ki_filp)->i_sb, + SB_FREEZE_WRITE); + file_end_write(iocb->ki_filp); + fuse_copyattr(iocb_fuse->ki_filp, iocb->ki_filp); + } + + iocb_fuse->ki_pos = iocb->ki_pos; + kfree(aio_req); +} + +static void fuse_aio_rw_complete(struct kiocb *iocb, long res, long res2) +{ + struct fuse_aio_req *aio_req = + container_of(iocb, struct fuse_aio_req, iocb); + struct kiocb *iocb_fuse = aio_req->iocb_fuse; + + fuse_aio_cleanup_handler(aio_req); + iocb_fuse->ki_complete(iocb_fuse, res, res2); +} + ssize_t fuse_passthrough_read_iter(struct kiocb *iocb_fuse, struct iov_iter *iter) { @@ -56,7 +87,18 @@ ssize_t fuse_passthrough_read_iter(struct kiocb *iocb_fuse, ret = vfs_iter_read(passthrough_filp, iter, &iocb_fuse->ki_pos, iocbflags_to_rwf(iocb_fuse->ki_flags)); } else { - ret = -EIO; + struct fuse_aio_req *aio_req; + + aio_req = kmalloc(sizeof(struct fuse_aio_req), GFP_KERNEL); + if (!aio_req) + return -ENOMEM; + + aio_req->iocb_fuse = iocb_fuse; + kiocb_clone(&aio_req->iocb, iocb_fuse, passthrough_filp); + aio_req->iocb.ki_complete = fuse_aio_rw_complete; + ret = call_read_iter(passthrough_filp, &aio_req->iocb, iter); + if (ret != -EIOCBQUEUED) + fuse_aio_cleanup_handler(aio_req); } revert_creds(old_cred); @@ -72,6 +114,7 @@ ssize_t fuse_passthrough_write_iter(struct kiocb *iocb_fuse, struct fuse_file *ff = fuse_filp->private_data; struct inode *fuse_inode = file_inode(fuse_filp); struct file *passthrough_filp = ff->passthrough_filp; + struct inode *passthrough_inode = file_inode(passthrough_filp); if (!iov_iter_count(iter)) return 0; @@ -87,8 +130,25 @@ ssize_t fuse_passthrough_write_iter(struct kiocb *iocb_fuse, if (ret > 0) fuse_copyattr(fuse_filp, passthrough_filp); } else { - ret = -EIO; + struct fuse_aio_req *aio_req; + + aio_req = kmalloc(sizeof(struct fuse_aio_req), GFP_KERNEL); + if (!aio_req) { + ret = -ENOMEM; + goto out; + } + + file_start_write(passthrough_filp); + __sb_writers_release(passthrough_inode->i_sb, SB_FREEZE_WRITE); + + aio_req->iocb_fuse = iocb_fuse; + kiocb_clone(&aio_req->iocb, iocb_fuse, passthrough_filp); + aio_req->iocb.ki_complete = fuse_aio_rw_complete; + ret = call_write_iter(passthrough_filp, &aio_req->iocb, iter); + if (ret != -EIOCBQUEUED) + fuse_aio_cleanup_handler(aio_req); } +out: revert_creds(old_cred); inode_unlock(fuse_inode); -- 2.28.0.681.g6f77f65b4e-goog