Received: by 2002:a05:6a10:22f:0:0:0:0 with SMTP id 15csp390921pxk; Fri, 11 Sep 2020 09:38:17 -0700 (PDT) X-Google-Smtp-Source: ABdhPJyujgTtAlQFEnM8XJb/rkY5OE4EDo3ND5fs8sIMjS7rSlqI/CH6v5xkuCrjicKh7xl0Oqz/ X-Received: by 2002:a17:906:6805:: with SMTP id k5mr2729607ejr.397.1599842297031; Fri, 11 Sep 2020 09:38:17 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1599842297; cv=none; d=google.com; s=arc-20160816; b=cK2Mk6Foe/DaxJGKMX/BhqBB5JBuPFVm5MZkTXwpGbbM2nCGpngzyHINFgTfIqlWZX VyPlhCV7xwG5775a23RjLX1e/ty3uPJ53RbKIVizwT++1BaC4zChdISB0RM8zrJTyeIO 0nQAyeLDisb9rTx7zlmhj25GfESjYZwapspLyXZk+cH+h7V44FA8bdWn1N2lk49a3arG forzOs3ewfOKsGojWOSyv9Gfqan7yVJZdmR+qudmO+5qwefDiCQfmQUTbDBNsiAo4UYl yBK+pqMkqSm6A9rq7IsNLVqUyjDDA/+0yoCcq66vzsCFPQSuUh1YPuq2BFwM0gGeExxL g8kw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:content-transfer-encoding:mime-version :references:in-reply-to:message-id:date:subject:cc:to:from :dkim-signature; bh=4wulnUlhSwjyVg7HlchQMtmSPVSZJX7Gl9pTHnw54ME=; b=0Me2IyI0cozR4uGP1aZNY38pq0/VfKu4/2wvyz66BNIcU90/1nukyXjdPfqqUagdSo 2zWiWIKU2FhsKtUaqXu6uZBFJ01ReYiUe1TN3F5J6pWW0op2X4SCK8rXInl9EdP9panq 8x+etbr9+W2h9ZJhPGvxnpjIsYPvTZO/G8DPus9hC43oxDdo35Ka1HZrXbl6uCpJxh+1 KqVh4+s72rc532MBLRZMdPqdTNSoNEdyNynNODbihMSHRuS3oO0ZDorgRYfCuZwL2u5a adbWusb1BQW8CYFNjnfZP/stP2h5+XmMVpd2E9upyi11VUn7k7JQodWMN9lm1b288vlG lk1A== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@android.com header.s=20161025 header.b=I6Wa6qSL; 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 bo22si1669029edb.187.2020.09.11.09.37.54; Fri, 11 Sep 2020 09:38:17 -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=I6Wa6qSL; 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 S1725941AbgIKQfT (ORCPT + 99 others); Fri, 11 Sep 2020 12:35:19 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:44482 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726553AbgIKQfH (ORCPT ); Fri, 11 Sep 2020 12:35:07 -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 14243C061796 for ; Fri, 11 Sep 2020 09:34:54 -0700 (PDT) Received: by mail-wr1-x444.google.com with SMTP id m6so12134265wrn.0 for ; Fri, 11 Sep 2020 09:34:54 -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=4wulnUlhSwjyVg7HlchQMtmSPVSZJX7Gl9pTHnw54ME=; b=I6Wa6qSLug9wEb+0TV6tW9xlypmmgNWh4CFQZm00Syc3U4tMukiAY/znsvfFTwFmB1 1QYXXx3qf/WNKeIyR6oMx6LYCWuBApznuhNplBl36ycCMaHafe+IsTGMb/u26GQGxZpg KPTpobARRAkNGLlG5Fb1HXBEVAXoD2n5Tex57gI9T9W2DPCK3kSlwVkB1+9T9tGbG8yO wyrH1BPSZE9Go00wkVl58kLmaOS7facMaXB6iHJTpq/xflw6wvTFbQamKQuyeC25IPnl NhpQr4sjyqBhACPw8SrPvt4M9yuNUTYVue5+C48LyRj249xVi4C0lQb8xURL/uvdyDzq zfWA== 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=4wulnUlhSwjyVg7HlchQMtmSPVSZJX7Gl9pTHnw54ME=; b=iuN9zL6YE6yvEwwyYpealWEJMeByNbV9epzcC0jEryhcw+HQUVyupfer9c7Q5boe1U VjpIsRM06HeoNhdlovoB5lcQNTX7r4YcVMzisEzcbdwsXkZBECiChUe+pTvTl9rvMD1C Sej5k4j6WUou/MFRLUAX/Xq2JW2qw5M9J6LcC/EEeuRwQR95PgF+Zki9QLRY43qZ5MRP VxWrT5Btn+bDVHyI+rvDRBeTFd/u6v3N+4qeyw23s8WAkb+Wh0+G3kzR6MP0COj2Wtgd jNV+258vKLOEQ6GjXgEVaT7Uk2uqwFlQ0qL14awAuIUUlFXQQr1xiTewLdhD3WsX4nMh Iisg== X-Gm-Message-State: AOAM531KTVTlkDaS1RxvCvdbSvDdfZtU1lBif5No5dPJ6TdrsWGQevLo 9xCfhl97NU6lV4nz4/pcHaxy7A== X-Received: by 2002:adf:fa0c:: with SMTP id m12mr2807414wrr.406.1599842092777; Fri, 11 Sep 2020 09:34:52 -0700 (PDT) Received: from balsini.lon.corp.google.com ([2a00:79e0:d:210:7220:84ff:fe09:7d5c]) by smtp.gmail.com with ESMTPSA id s2sm5739912wrw.96.2020.09.11.09.34.51 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 11 Sep 2020 09:34:52 -0700 (PDT) From: Alessio Balsini To: Miklos Szeredi Cc: Akilesh Kailash , Amir Goldstein , David Anderson , Eric Yan , 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 V8 3/3] fuse: Handle AIO read and write in passthrough Date: Fri, 11 Sep 2020 17:34:03 +0100 Message-Id: <20200911163403.79505-4-balsini@android.com> X-Mailer: git-send-email 2.28.0.618.gf4bc123cb7-goog In-Reply-To: <20200911163403.79505-1-balsini@android.com> References: <20200911163403.79505-1-balsini@android.com> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit Sender: linux-kernel-owner@vger.kernel.org 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, targeting a FUSE file with passthrough functionality enabled, a new identical AIO request is created, the file pointer of which is updated with the file pointer of the lower file system, and the completion handler is set with a special AIO passthrough handler. The lower file system AIO request is allocated in dynamic kernel memory and, when it completes, the allocated memory is freed and the completion signal is propagated to the FUSE AIO request by triggering its completion callback as well. Signed-off-by: Alessio Balsini --- fs/fuse/passthrough.c | 66 +++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 63 insertions(+), 3 deletions(-) diff --git a/fs/fuse/passthrough.c b/fs/fuse/passthrough.c index 44a78e02f45d..87b57b26fd8a 100644 --- a/fs/fuse/passthrough.c +++ b/fs/fuse/passthrough.c @@ -2,10 +2,16 @@ #include "fuse_i.h" +#include #include #include #include +struct fuse_aio_req { + struct kiocb iocb; + struct kiocb *iocb_fuse; +}; + static void fuse_copyattr(struct file *dst_file, struct file *src_file, bool write) { @@ -20,6 +26,32 @@ static void fuse_copyattr(struct file *dst_file, struct file *src_file, } } +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; + bool write = !!(iocb->ki_flags & IOCB_WRITE); + + if (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, write); + 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) @@ -42,7 +74,18 @@ ssize_t fuse_passthrough_read_iter(struct kiocb *iocb_fuse, fuse_copyattr(fuse_filp, passthrough_filp, false); } 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); } return ret; @@ -56,6 +99,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; @@ -75,9 +119,25 @@ ssize_t fuse_passthrough_write_iter(struct kiocb *iocb_fuse, if (ret > 0) fuse_copyattr(fuse_filp, passthrough_filp, true); } 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: inode_unlock(fuse_inode); return ret; -- 2.28.0.618.gf4bc123cb7-goog