From patchwork Tue Apr 26 17:43:29 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Stefan Roesch X-Patchwork-Id: 12827657 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from kanga.kvack.org (kanga.kvack.org [205.233.56.17]) by smtp.lore.kernel.org (Postfix) with ESMTP id 3CC57C4332F for ; Tue, 26 Apr 2022 17:44:14 +0000 (UTC) Received: by kanga.kvack.org (Postfix) id A50036B0087; Tue, 26 Apr 2022 13:44:13 -0400 (EDT) Received: by kanga.kvack.org (Postfix, from userid 40) id 9D7566B0088; Tue, 26 Apr 2022 13:44:13 -0400 (EDT) X-Delivered-To: int-list-linux-mm@kvack.org Received: by kanga.kvack.org (Postfix, from userid 63042) id 8512C6B0089; Tue, 26 Apr 2022 13:44:13 -0400 (EDT) X-Delivered-To: linux-mm@kvack.org Received: from relay.hostedemail.com (relay.a.hostedemail.com [64.99.140.24]) by kanga.kvack.org (Postfix) with ESMTP id 5B9AE6B0087 for ; Tue, 26 Apr 2022 13:44:13 -0400 (EDT) Received: from smtpin30.hostedemail.com (a10.router.float.18 [10.200.18.1]) by unirelay13.hostedemail.com (Postfix) with ESMTP id 44CD360C72 for ; Tue, 26 Apr 2022 17:44:13 +0000 (UTC) X-FDA: 79399753986.30.BA1B485 Received: from mx0a-00082601.pphosted.com (mx0a-00082601.pphosted.com [67.231.145.42]) by imf30.hostedemail.com (Postfix) with ESMTP id E66568004B for ; Tue, 26 Apr 2022 17:44:05 +0000 (UTC) Received: from pps.filterd (m0148461.ppops.net [127.0.0.1]) by mx0a-00082601.pphosted.com (8.17.1.5/8.17.1.5) with ESMTP id 23QGQTgG003362 for ; Tue, 26 Apr 2022 10:44:11 -0700 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=fb.com; h=from : to : cc : subject : date : message-id : in-reply-to : references : mime-version : content-transfer-encoding : content-type; s=facebook; bh=jmjAEmB9SiHspC6uI3myhKQiRIbn+/4Qt69A1DT8ia0=; b=Zgg3nW5dYR2UauB5q7DxHZVdh66nXEd44fvPQNix0yeThM8IpG5L090tB3wfPp/Tovb3 D92X11viQFm6QGgikw/9JrU6U3rqV4Ol0VJglp/jcZxjTmj5MgqiK/yfzmhRLZTJra/0 rpy6jInFIrrGnbOjlYRJzxHbPSErnXOqRdc= Received: from maileast.thefacebook.com ([163.114.130.16]) by mx0a-00082601.pphosted.com (PPS) with ESMTPS id 3fp6a352qf-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128 verify=NOT) for ; Tue, 26 Apr 2022 10:44:11 -0700 Received: from twshared4937.07.ash9.facebook.com (2620:10d:c0a8:1b::d) by mail.thefacebook.com (2620:10d:c0a8:82::d) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.2375.24; Tue, 26 Apr 2022 10:44:10 -0700 Received: by devvm225.atn0.facebook.com (Postfix, from userid 425415) id BD5F5E2D486B; Tue, 26 Apr 2022 10:43:40 -0700 (PDT) From: Stefan Roesch To: , , , , CC: , Subject: [RFC PATCH v1 12/18] io_uring: add support for async buffered writes Date: Tue, 26 Apr 2022 10:43:29 -0700 Message-ID: <20220426174335.4004987-13-shr@fb.com> X-Mailer: git-send-email 2.30.2 In-Reply-To: <20220426174335.4004987-1-shr@fb.com> References: <20220426174335.4004987-1-shr@fb.com> MIME-Version: 1.0 X-FB-Internal: Safe X-Proofpoint-GUID: WhpJ7BD3fMlfl-RsRqgB4xwBDKtNqIER X-Proofpoint-ORIG-GUID: WhpJ7BD3fMlfl-RsRqgB4xwBDKtNqIER X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.205,Aquarius:18.0.858,Hydra:6.0.486,FMLib:17.11.64.514 definitions=2022-04-26_05,2022-04-26_02,2022-02-23_01 X-Stat-Signature: kkuuesw88pjhy6pwt38h8wzkydyyox65 X-Rspamd-Server: rspam12 X-Rspamd-Queue-Id: E66568004B Authentication-Results: imf30.hostedemail.com; dkim=pass header.d=fb.com header.s=facebook header.b=Zgg3nW5d; spf=none (imf30.hostedemail.com: domain of "prvs=5115329de3=shr@fb.com" has no SPF policy when checking 67.231.145.42) smtp.mailfrom="prvs=5115329de3=shr@fb.com"; dmarc=pass (policy=reject) header.from=fb.com X-Rspam-User: X-HE-Tag: 1650995045-31229 X-Bogosity: Ham, tests=bogofilter, spamicity=0.000000, version=1.2.4 Sender: owner-linux-mm@kvack.org Precedence: bulk X-Loop: owner-majordomo@kvack.org List-ID: This enables the async buffered writes for the filesystems that support async buffered writes in io-uring. Buffered writes are enabled for blocks that are already in the page cache or can be acquired with noio. Signed-off-by: Stefan Roesch --- fs/io_uring.c | 29 ++++++++++++++++++++++++----- 1 file changed, 24 insertions(+), 5 deletions(-) diff --git a/fs/io_uring.c b/fs/io_uring.c index 7625b29153b9..2ba615374ba4 100644 --- a/fs/io_uring.c +++ b/fs/io_uring.c @@ -3746,7 +3746,7 @@ static inline int io_iter_do_read(struct io_kiocb *req, struct iov_iter *iter) return -EINVAL; } -static bool need_read_all(struct io_kiocb *req) +static bool need_complete_io(struct io_kiocb *req) { return req->flags & REQ_F_ISREG || S_ISBLK(file_inode(req->file)->i_mode); @@ -3874,7 +3874,7 @@ static int io_read(struct io_kiocb *req, unsigned int issue_flags) } else if (ret == -EIOCBQUEUED) { goto out_free; } else if (ret == req->result || ret <= 0 || !force_nonblock || - (req->flags & REQ_F_NOWAIT) || !need_read_all(req)) { + (req->flags & REQ_F_NOWAIT) || !need_complete_io(req)) { /* read all, failed, already did sync or don't want to retry */ goto done; } @@ -3970,9 +3970,10 @@ static int io_write(struct io_kiocb *req, unsigned int issue_flags) if (unlikely(!io_file_supports_nowait(req))) goto copy_iov; - /* file path doesn't support NOWAIT for non-direct_IO */ - if (force_nonblock && !(kiocb->ki_flags & IOCB_DIRECT) && - (req->flags & REQ_F_ISREG)) + /* File path supports NOWAIT for non-direct_IO only for block devices. */ + if (!(kiocb->ki_flags & IOCB_DIRECT) && + !(kiocb->ki_filp->f_mode & FMODE_BUF_WASYNC) && + (req->flags & REQ_F_ISREG)) goto copy_iov; kiocb->ki_flags |= IOCB_NOWAIT; @@ -4026,6 +4027,24 @@ static int io_write(struct io_kiocb *req, unsigned int issue_flags) /* IOPOLL retry should happen for io-wq threads */ if (ret2 == -EAGAIN && (req->ctx->flags & IORING_SETUP_IOPOLL)) goto copy_iov; + + if (ret2 != req->result && ret2 >= 0 && need_complete_io(req)) { + struct io_async_rw *rw; + + /* This is a partial write. The file pos has already been + * updated, setup the async struct to complete the request + * in the worker. Also update bytes_done to account for + * the bytes already written. + */ + iov_iter_save_state(&s->iter, &s->iter_state); + ret = io_setup_async_rw(req, iovec, s, true); + + rw = req->async_data; + if (rw) + rw->bytes_done += ret2; + + return ret ? ret : -EAGAIN; + } done: kiocb_done(req, ret2, issue_flags); } else {