Received: by 2002:a05:6a10:22f:0:0:0:0 with SMTP id 15csp4796838pxk; Wed, 30 Sep 2020 11:55:49 -0700 (PDT) X-Google-Smtp-Source: ABdhPJwc1OFcZmcNymIzM7oQ/hadIqDbvKNe4kqv2PpFqmHcAQvJuAQiicJt5lfgxe464/Or+Awj X-Received: by 2002:a17:906:b858:: with SMTP id ga24mr3144462ejb.378.1601492149468; Wed, 30 Sep 2020 11:55:49 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1601492149; cv=none; d=google.com; s=arc-20160816; b=fn5sblMOHBgoeN48vFxy2YIxh8JelaZ/H22V1cCEwRQHbbNPtHhW5ZfqTsjtUbbyxj wGFde/BDYeYhypxf4y6i2GWKqYlnYnWL3aRTATJ1/zgoOPW5Z07sHuxgPL0thzJdf6iC GZ0bKHiN0aHLPEbtz2EYrR6G3IsIKGEYNor3HiyIz5J2sicAx6kZEcU7bjO/ZPlixWcQ zGfSMiFOzH64T+Zxvo77nufaSjMtU6SLGSjr1XrfAJ45DNPfUS+yX7sr4bQ6K5qmM6W7 Wv1lrNI2ESgBjGrTG4E9v5M0ZEjBolteGH7HF7fyyPCjQGL601lCLquKyKf7DQ1EiLHh Mssg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:cc:to:subject:message-id:date:from:in-reply-to :references:mime-version:dkim-signature; bh=N2Atg0nwqil3CgBKoVorL+M9yJnmhZns2R4gE+7lVFU=; b=kePoECe981zngGjoIcB7q3ztCslf2e0zJQ9WhMfHSyUion30AR1hXWRgyUmxuo8dui 35Sew0Cbi/+O0eUgpXBbN2Oi5vYk2m6Ln3jiwZpsxV/wqiFHMNoanGLbYhzrgMoI2VG1 HFwGjHXwk4z0oNwFBZTSpVA37WOXoiiTXGbanEG47iBaBEhXIjTAJ9/jVuSc49uMyMqP k3LSmE9qqab0Wi4oj3ttnFu5BFHIpHD9wXySSEWddBdaVxkLWtxu0QsMU8O3YWc15+oW nP8QHBIs6Y6zrf8JHDv3u+iyDLDdUopd5JjfvRRIzG+ZnlU8tvB6qKVHmpn1baYE5ITs 1TiA== ARC-Authentication-Results: i=1; mx.google.com; dkim=temperror (no key for signature) header.i=@szeredi.hu header.s=google header.b="JApnnR/2"; 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 Return-Path: Received: from vger.kernel.org (vger.kernel.org. [23.128.96.18]) by mx.google.com with ESMTP id l14si1761261ejz.622.2020.09.30.11.55.26; Wed, 30 Sep 2020 11:55:49 -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=temperror (no key for signature) header.i=@szeredi.hu header.s=google header.b="JApnnR/2"; 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 Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728679AbgI3SyP (ORCPT + 99 others); Wed, 30 Sep 2020 14:54:15 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:45824 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1728368AbgI3SyP (ORCPT ); Wed, 30 Sep 2020 14:54:15 -0400 Received: from mail-vs1-xe43.google.com (mail-vs1-xe43.google.com [IPv6:2607:f8b0:4864:20::e43]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 73327C0613D0 for ; Wed, 30 Sep 2020 11:54:15 -0700 (PDT) Received: by mail-vs1-xe43.google.com with SMTP id e23so1466363vsk.2 for ; Wed, 30 Sep 2020 11:54:15 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=szeredi.hu; s=google; h=mime-version:references:in-reply-to:from:date:message-id:subject:to :cc; bh=N2Atg0nwqil3CgBKoVorL+M9yJnmhZns2R4gE+7lVFU=; b=JApnnR/2Y5mntj/oYjVcB3SzT3WVFZfmvREkja+Y8cZtnI/8HEkwWIbz1nC9aLrFq+ 1nk63fQYtJKR/5+OGMqXIAcO/4sBF7Z1NLqmQtekSVptYsR2N7HOU4uZ09oQZbFjJwZO pzaTSKC1HsnFMn8d5no5ve2hSFD/IkgnJJOns= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:mime-version:references:in-reply-to:from:date :message-id:subject:to:cc; bh=N2Atg0nwqil3CgBKoVorL+M9yJnmhZns2R4gE+7lVFU=; b=nhT88Uts4IrglDH2MQBxu4eatlbddGR5ADcf8yeRjJ7vUARBpCpZ8PwfqsSPwONEL0 W6eLrl5pvEFnIVynL7qSxyr+0Bd8eVTPkZ00J1lEW/PIAhRu6KrMx6PC50c297NNvIcM 36pXhlLOn222QeLQ/3+CKfu/1m9JnLIdsIyaT05Kja3RbRvLB/m1wkEce2r3B6c3bGC+ Tr8tpIrQIaeijbDTaXEoQt3I3KWD+Tav6aEu13zIeor598ttxJw8yp+28JwrzpkIet43 h/KeQeNEilLmceGDedBtQpdGmfGAN07S0XGgO4jecxP8kc654CfnmmI1gEKZBIR6ANgA mg2A== X-Gm-Message-State: AOAM530ZNedOXmmBtiIyA8JzI+xiDxk/hCR/6Se6joiOvk9ICyrM7FFV IS8QHI8M7QEl6L0q/yi5JH8D3AEmSHtoKLKorjhFUQ== X-Received: by 2002:a67:6952:: with SMTP id e79mr2901081vsc.4.1601492054633; Wed, 30 Sep 2020 11:54:14 -0700 (PDT) MIME-Version: 1.0 References: <20200924131318.2654747-1-balsini@android.com> <20200924131318.2654747-5-balsini@android.com> In-Reply-To: <20200924131318.2654747-5-balsini@android.com> From: Miklos Szeredi Date: Wed, 30 Sep 2020 20:54:03 +0200 Message-ID: Subject: Re: [PATCH V9 4/4] fuse: Handle asynchronous read and write in passthrough To: Alessio Balsini 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 , kernel-team , linux-fsdevel@vger.kernel.org, linux-kernel@vger.kernel.org Content-Type: text/plain; charset="UTF-8" Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org On Thu, Sep 24, 2020 at 3:13 PM Alessio Balsini wrote: > > 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. This ends up with almost identical code in fuse and overlayfs, right? Maybe it's worth looking into moving these into common helpers. Thanks, Miklos > > 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 >