Received: by 2002:a05:6a10:9e8c:0:0:0:0 with SMTP id y12csp195190pxx; Mon, 26 Oct 2020 06:37:22 -0700 (PDT) X-Google-Smtp-Source: ABdhPJyCBpMsdJ7eyfoiQBGvLa6/N0BSsUrLJqXPbKXk/so9cMGgd+pvuGwuh4rAlMGSgApWlhfy X-Received: by 2002:aa7:d65a:: with SMTP id v26mr15981991edr.82.1603719442205; Mon, 26 Oct 2020 06:37:22 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1603719442; cv=none; d=google.com; s=arc-20160816; b=KUy3+ihqIOO3eF5FOfG/UmfRbvu88Q54/a6qJ+knIjU2gdrjU/FPxNheMIfmzvjH8Y FH37lN0VAjPhYnvDc6FszOIoAcy87ub4XJvMkRV4YLX272UzwRyHySUrxvdeca3SR7ck Xp7uwP0/6c9OjsJJU4nTpqg/kagj9Y4vc8/+O/E/WLTw+M1o117VOO+ZExGkxCEpcH+o wJ8EZ/kBwNUFpICMmKrcCs/njQYmftD+n4wWIG0fTpkq/OXvnFlyRd6NrZOVlveRSMmw TibhpXRveg3Ac1zacjZ7AtvZAYozmWt6tFfQpI/MsQRKvU/kUixwJGtpbLgXbZFxDZSN yQEg== 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=9eIClT5rENq9kBsjIFF+DaoCpFvJQstMih7FfG4bpQI=; b=i8sgUlEI7veBJZoDGN414eAZuUXY7P/ZYahRWsoENIuw/lXr5Z/RkX1oh3XDUDOaF4 O4mVt0VvT0TB3NHSxRLxmlttlqJcRrYM+GNZn3MDTV5TT2zd8QGon9174+9g6SsAXvxc FURieyu2RFvl8Q+DTprNksiGH5lVxVGQ+dPudI8LuGrV1Epj1eiHBidal/312kiJSOVs GgBn/TKeyLv4/0MkhdEj9xRIYfDIg9HJpkrvuamLJIlViLj/jtxFs5t727/T7HOmMxIm Ih4vdbinBWdPlYISvbFFOAF1N2RL3Rm+o1R7+TfG524x0LFAMepvqYSZ7A7kaTIGU177 iqEA== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@android.com header.s=20161025 header.b=JDXJgSQJ; 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 hh9si7406460ejb.38.2020.10.26.06.36.59; Mon, 26 Oct 2020 06:37:22 -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=JDXJgSQJ; 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 S1775620AbgJZMvw (ORCPT + 99 others); Mon, 26 Oct 2020 08:51:52 -0400 Received: from mail-wr1-f65.google.com ([209.85.221.65]:36837 "EHLO mail-wr1-f65.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1775614AbgJZMvw (ORCPT ); Mon, 26 Oct 2020 08:51:52 -0400 Received: by mail-wr1-f65.google.com with SMTP id x7so12399422wrl.3 for ; Mon, 26 Oct 2020 05:51:49 -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=9eIClT5rENq9kBsjIFF+DaoCpFvJQstMih7FfG4bpQI=; b=JDXJgSQJ80djfaAPRIOkY7qkWmZDRbS9SFL476HVIgjsAc6wSRP1/i/v1IV8BMMYkp B0EXwBBKYxl9+AGFZ4g/QiSgQ2Qjwh8a1W9uCMGhSrkaoV9bhAc8vQKI0pMz4TpbVugL l9LBQsJCbYz7EZZ3ceGl/XYGw6QQ69Pz/gzHcm3PBAtl2mbGYSdGHgRqvLdZ6SALcNBG 50tu3ZWj0GYObEaxLQ9JTZMCL1rHqgAMqIR4CCbY8sNXhD2dsInDHE5FmQQG9PozEd5f tT1UeQYxanLapsSaHir/m/ta4wr1rRd6ZAPhzMXeNtNrey4ICU9KsVoXmPtM9rHi8zlt JCTQ== 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=9eIClT5rENq9kBsjIFF+DaoCpFvJQstMih7FfG4bpQI=; b=lvBl9ge+lFYUkFUwXs/DURp5RNiuM4AJSx0L+78tiDK8MricRVRICYOWSgoaiPkE9j zVZFMr838Rns5tet5NAOecSqtQN4zHNSwWGAY6/g1AEei1BMVngMTa3XCn4XK/qel58W f7oAhfOMF9K2zVNshFSskkkoA4yTurA/ibM6eXku1cwNGloJWVjImRFN8OsLY0wbrUod gSDRwvX4HGE3Xii9MclDvjd6Ad6sM5NwkdWJzGAHA382Csh9k61Pj4D6IDAZf1V+6uD2 znvvNtpVM/33dt2WoR+p6+Kc6FM7bRZxC1GoyBBZWhIlVcOwD9c4Eu/BePKL/KnBW4vO f8Dg== X-Gm-Message-State: AOAM533PMIzkkypyZ1mW0ZjZ8S3WJRbWZPhfPiYEVcI2JQat9mapKzTW qi2I0dZnNApFHcASwYsmVkB5KQ== X-Received: by 2002:a5d:410a:: with SMTP id l10mr17506394wrp.274.1603716709164; Mon, 26 Oct 2020 05:51:49 -0700 (PDT) Received: from balsini.lon.corp.google.com ([2a00:79e0:d:210:7220:84ff:fe09:7d5c]) by smtp.gmail.com with ESMTPSA id r1sm24423262wro.18.2020.10.26.05.51.48 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 26 Oct 2020 05:51:48 -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 V10 4/5] fuse: Handle asynchronous read and write in passthrough Date: Mon, 26 Oct 2020 12:50:15 +0000 Message-Id: <20201026125016.1905945-5-balsini@android.com> X-Mailer: git-send-email 2.29.0.rc1.297.gfa9743e501-goog In-Reply-To: <20201026125016.1905945-1-balsini@android.com> References: <20201026125016.1905945-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 | 85 ++++++++++++++++++++++++++++++++++++++----- 1 file changed, 76 insertions(+), 9 deletions(-) diff --git a/fs/fuse/passthrough.c b/fs/fuse/passthrough.c index 5a78cb336db4..10b6872cdaa7 100644 --- a/fs/fuse/passthrough.c +++ b/fs/fuse/passthrough.c @@ -6,6 +6,11 @@ #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) { struct inode *dst = file_inode(dst_file); @@ -32,6 +37,32 @@ static inline rwf_t iocb_to_rw_flags(int ifl) return flags; } +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) { @@ -43,8 +74,23 @@ ssize_t fuse_passthrough_read_iter(struct kiocb *iocb_fuse, if (!iov_iter_count(iter)) return 0; - ret = vfs_iter_read(passthrough_filp, iter, &iocb_fuse->ki_pos, - iocb_to_rw_flags(iocb_fuse->ki_flags)); + if (is_sync_kiocb(iocb_fuse)) { + ret = vfs_iter_read(passthrough_filp, iter, &iocb_fuse->ki_pos, + iocb_to_rw_flags(iocb_fuse->ki_flags)); + } else { + 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; } @@ -57,19 +103,40 @@ 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; inode_lock(fuse_inode); - file_start_write(passthrough_filp); - ret = vfs_iter_write(passthrough_filp, iter, &iocb_fuse->ki_pos, - iocb_to_rw_flags(iocb_fuse->ki_flags)); - file_end_write(passthrough_filp); - if (ret > 0) - fuse_copyattr(fuse_filp, passthrough_filp); - + if (is_sync_kiocb(iocb_fuse)) { + file_start_write(passthrough_filp); + ret = vfs_iter_write(passthrough_filp, iter, &iocb_fuse->ki_pos, + iocb_to_rw_flags(iocb_fuse->ki_flags)); + file_end_write(passthrough_filp); + if (ret > 0) + fuse_copyattr(fuse_filp, passthrough_filp); + } else { + 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.29.0.rc1.297.gfa9743e501-goog