Received: by 2002:a05:6a10:8c0a:0:0:0:0 with SMTP id go10csp2498598pxb; Mon, 18 Jan 2021 21:15:42 -0800 (PST) X-Google-Smtp-Source: ABdhPJzkMT6Po4H3UVpbokXysPA0Bk7d/fRzSqDdYbUXnsHeX7Mx/F0hhI0jjZvangWFLZV9dkPb X-Received: by 2002:a50:8b66:: with SMTP id l93mr1938921edl.384.1611033341955; Mon, 18 Jan 2021 21:15:41 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1611033341; cv=none; d=google.com; s=arc-20160816; b=T9f7iTSqGGYQXH1zI2DOh3lKtKejgSCSicjapPWxllk35F1mX3ZAWMQIeu9FelLw1u fU//grqujNlxLc9iZuU5Pc8czcpYHKNdCnTBKpZFcGVyMBqAnDbGwu6Ve5TGqe1iuR1s egq4NF2F2iMqgL/cXWRWKxcCb6gOXLeV4+eka5OadY7ZEcqJM5K/iyT204WpVR9pSg5L MFn+xv97f3WSM4me+K17fOL/Av/vr/Ndt/p/tz5XcziV+3yPUi6mMBv7kgYNI86jEyhl P9ExILYMkTDHLd9Pk7QpJYDATEIuJWgqojcOvl7NdwjWQpahdgk4Nrw6UcZUKh3bvYjD x0fQ== 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=rKB9lEn/LGchi0nKMk+V258K5toceSfY+t698Ueu4z0=; b=gRb6VNfsc++R+UCo6CuDUOElS80bwzZ3DiGsZF6hYRwjUXtewjZUQ5qlTyjYySepsm yu9JC+60MAubVKdxduBusV38XfwB2D1bVTyiYhOrZGuWSPlVoNz7LGm23NZ+x44nffhA 9OsC8Yb3wG0a9PBEFfBOc9o5dpE4hDG+9TUxv/ZP2ZxKXjUOMxdGOJYgBZLCrh9u5sl1 tRkVDzvHFeiFjwp6w0WBkiLYU1hI13v5yZ1V8vudDNS2oiHtAvcOReJ5VBxNph5/Fqbr PGDQ7WRs/jKMIpGSzCj5n8++IG1EP9DFy+yLgP7dj5vomOGldVBZuH5fetHo5c/jKP97 CPtw== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@android.com header.s=20161025 header.b=T5+u1mt0; 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 gj13si4569813ejb.41.2021.01.18.21.15.18; Mon, 18 Jan 2021 21:15:41 -0800 (PST) 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=T5+u1mt0; 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 S2437091AbhARTow (ORCPT + 99 others); Mon, 18 Jan 2021 14:44:52 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:34200 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S2437215AbhARTaS (ORCPT ); Mon, 18 Jan 2021 14:30:18 -0500 Received: from mail-wm1-x332.google.com (mail-wm1-x332.google.com [IPv6:2a00:1450:4864:20::332]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 7E62AC061799 for ; Mon, 18 Jan 2021 11:29:06 -0800 (PST) Received: by mail-wm1-x332.google.com with SMTP id c124so14565619wma.5 for ; Mon, 18 Jan 2021 11:29:06 -0800 (PST) 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=rKB9lEn/LGchi0nKMk+V258K5toceSfY+t698Ueu4z0=; b=T5+u1mt0y6k6Isp16kGrpGqeV2EXtm82ppcOPxUDINZaE8bADOe/+j5oXkTeUPK7Ut NPvQnoU5pCdLkJUBw4zCxouiZ6LFW1HCXK9qKXuwIRH+VMvDSd7oWWLPEB56pO9ZDQWZ VYoaHP2SOlzIAP9ZkcK58QBXD3F3YJRKtvRqw9GXu80jDXX4ZBH3CVTj2ak/8PhqS59O /w5RehdRlne49H9NEATW8e39Ac5J4tJ2IKxYWTQx/odJLbyhjsyh2KYLXT8I3Oztjmkc k33n6y9UULrZFybJ9IzvIYWW4QP9dXN4OWhiiyzSgGcT00UQigExMLDXS0V0Qjr6bNI6 nurw== 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=rKB9lEn/LGchi0nKMk+V258K5toceSfY+t698Ueu4z0=; b=OQr9DiFyztfVmuvjgqEgJyIxqQ8b42L48ACEcdaK68J6VWawnMA3NRfY0/AP1Jfd5x TaSeNj8v/CDAeiGomZXYyvvwv+urpppxdZV1ikRf6jtomPM3uFkYog93SC93FnlI3CWw UNCpiWg2rFbUQGKCCObVVjuhxuc2j/rIWI0Vb3gcDZ8STuM/Sr5B/RB+UmB43pUpKkJt QyKy+m/63E4MXfgOR8K0VkUQ4vbbSEAFJA11zYyPHsN+eXuZd6lchJy9EyN7OFNYJ5/w HTMjoFvuQoqowcdeSUu6KsgA278J5d5mPjzez0/LH6ACZxSUafbNNtawDIua9hHM/Ypu Tu7g== X-Gm-Message-State: AOAM533KSZ4GzUF1WLJOvpc31zGRBYrra8hJpZsEF/ZYmvw6Gj/twSGA xVSZCcxsIUN9ihlVBvBmKjwUGQ== X-Received: by 2002:a1c:e4c5:: with SMTP id b188mr842882wmh.78.1610998145235; Mon, 18 Jan 2021 11:29:05 -0800 (PST) Received: from balsini.lon.corp.google.com ([2a00:79e0:d:210:41d4:8c90:d38:455d]) by smtp.gmail.com with ESMTPSA id h5sm33583299wrp.56.2021.01.18.11.29.04 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 18 Jan 2021 11:29:04 -0800 (PST) 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 , Peng Tao , Stefano Duo , Zimuzo Ezeozue , wuyan , fuse-devel@lists.sourceforge.net, kernel-team@android.com, linux-fsdevel@vger.kernel.org, linux-kernel@vger.kernel.org Subject: [PATCH RESEND V11 6/7] fuse: Handle asynchronous read and write in passthrough Date: Mon, 18 Jan 2021 19:27:47 +0000 Message-Id: <20210118192748.584213-7-balsini@android.com> X-Mailer: git-send-email 2.30.0.284.gd98b1dd5eaa7-goog In-Reply-To: <20210118192748.584213-1-balsini@android.com> References: <20210118192748.584213-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 | 89 +++++++++++++++++++++++++++++++++++++------ 1 file changed, 78 insertions(+), 11 deletions(-) diff --git a/fs/fuse/passthrough.c b/fs/fuse/passthrough.c index 8f6882a31a0b..da71a74014d7 100644 --- a/fs/fuse/passthrough.c +++ b/fs/fuse/passthrough.c @@ -9,6 +9,11 @@ #define PASSTHROUGH_IOCB_MASK \ (IOCB_APPEND | IOCB_DSYNC | IOCB_HIPRI | IOCB_NOWAIT | IOCB_SYNC) +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); @@ -17,6 +22,32 @@ static void fuse_copyattr(struct file *dst_file, struct file *src_file) i_size_write(dst, i_size_read(src)); } +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) { @@ -28,9 +59,24 @@ 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, - PASSTHROUGH_IOCB_MASK)); + 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, + PASSTHROUGH_IOCB_MASK)); + } 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; } @@ -43,20 +89,41 @@ 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, - PASSTHROUGH_IOCB_MASK)); - 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, + PASSTHROUGH_IOCB_MASK)); + 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.30.0.284.gd98b1dd5eaa7-goog