Received: by 2002:ac0:a582:0:0:0:0:0 with SMTP id m2-v6csp1366971imm; Tue, 2 Oct 2018 07:10:20 -0700 (PDT) X-Google-Smtp-Source: ACcGV62jvhQ5d7eJHWqtfWYOaaLQPHEIiRgyBI7fL+FbuZ7zG1pD3+KuQWKeLUcH1X7EpIiD3AQt X-Received: by 2002:a63:fb09:: with SMTP id o9-v6mr14648380pgh.333.1538489420270; Tue, 02 Oct 2018 07:10:20 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1538489420; cv=none; d=google.com; s=arc-20160816; b=kS2BNWyKP6Ut2ejP05eL0U7Vy0SCmXQtglYY14u6rBK67sHzo+njfGeHqHkiCfSo7d q1kH6HPitDH9qwFQErhKnFaiI+qUdGF35Djv6C7JxX6AAEiZb6O5q9uke0ksnGRW3fZ1 iCM7dzgGlUCkFggnQFNtFggchSfFZfBzBZC9FstI5NltLkfJy82lYwrTL8sWp9JBr9qh CgVS7ca83vysMK6j9fq09UXLxHn6SKWxECFk796DujpQUr8JgBONbeHbWaYCW7+D2lzW VgEhcYTFvJZQmMZi2tibb2OjSkbmB5RuITXcN1RMDMRt4pP088Mj/5/1qavUXXdtDs0+ b16Q== 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 :user-agent:references:in-reply-to:message-id:date:subject:cc:to :from; bh=wKbgyBQWdy1vSE0Rb6Oir9sw8AnhgFwpBFME4tu5uN4=; b=T1AYj1jh9nWu36oKQ5dJkFM0RODIWZpFk7XMLX+xpO+2P5RVSWLQ+jBIOBXBm0/zg0 K4FK0cjFhPW3hZLS3Mcuf4bDSwgXNLx79UHh7zpo68F0bZEq8cuPRMlLg9RmNWlXmH3w HAHQRDT0h1gzJWy5Unyhnf2cYi4W9Zq3r2yw1KGEv1NHixZH4RLMSwjMePXtTHbttnEw xyhXfTZ5h3X9950LGAPSuJUKDZqONp0FDWLuE9vfPAKFnnCgKFz9k+KeDie6gxSeaIdA hqds6XiT2vx1Bhwpgt281wbj+FaJC6BtAgOGKIp0+fM6op2k09bnhmfiD1ajHuiS2rCz QDBg== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id 11-v6si10424903plc.224.2018.10.02.07.10.04; Tue, 02 Oct 2018 07:10:20 -0700 (PDT) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1729274AbeJBULp (ORCPT + 99 others); Tue, 2 Oct 2018 16:11:45 -0400 Received: from mail.linuxfoundation.org ([140.211.169.12]:60928 "EHLO mail.linuxfoundation.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1729191AbeJBULo (ORCPT ); Tue, 2 Oct 2018 16:11:44 -0400 Received: from localhost (24-104-73-23-ip-static.hfc.comcastbusiness.net [24.104.73.23]) by mail.linuxfoundation.org (Postfix) with ESMTPSA id 3B8C9BF0; Tue, 2 Oct 2018 13:28:22 +0000 (UTC) From: Greg Kroah-Hartman To: linux-kernel@vger.kernel.org Cc: Greg Kroah-Hartman , stable@vger.kernel.org, Andreas Gruenbacher , Christoph Hellwig , "Darrick J. Wong" , Sasha Levin Subject: [PATCH 4.18 106/228] iomap: complete partial direct I/O writes synchronously Date: Tue, 2 Oct 2018 06:23:23 -0700 Message-Id: <20181002132506.554873308@linuxfoundation.org> X-Mailer: git-send-email 2.19.0 In-Reply-To: <20181002132459.032960735@linuxfoundation.org> References: <20181002132459.032960735@linuxfoundation.org> User-Agent: quilt/0.65 X-stable: review MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org 4.18-stable review patch. If anyone has any objections, please let me know. ------------------ From: Andreas Gruenbacher [ Upstream commit ebf00be37de35788cad72f4f20b4a39e30c0be4a ] According to xfstest generic/240, applications seem to expect direct I/O writes to either complete as a whole or to fail; short direct I/O writes are apparently not appreciated. This means that when only part of an asynchronous direct I/O write succeeds, we can either fail the entire write, or we can wait for the partial write to complete and retry the remaining write as buffered I/O. The old __blockdev_direct_IO helper has code for waiting for partial writes to complete; the new iomap_dio_rw iomap helper does not. The above mentioned fallback mode is needed for gfs2, which doesn't allow block allocations under direct I/O to avoid taking cluster-wide exclusive locks. As a consequence, an asynchronous direct I/O write to a file range that contains a hole will result in a short write. In that case, wait for the short write to complete to allow gfs2 to recover. Signed-off-by: Andreas Gruenbacher Signed-off-by: Christoph Hellwig Reviewed-by: Darrick J. Wong Signed-off-by: Darrick J. Wong Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman --- fs/iomap.c | 21 +++++++++++---------- 1 file changed, 11 insertions(+), 10 deletions(-) --- a/fs/iomap.c +++ b/fs/iomap.c @@ -811,6 +811,7 @@ struct iomap_dio { atomic_t ref; unsigned flags; int error; + bool wait_for_completion; union { /* used during submission and for synchronous completion: */ @@ -914,9 +915,8 @@ static void iomap_dio_bio_end_io(struct iomap_dio_set_error(dio, blk_status_to_errno(bio->bi_status)); if (atomic_dec_and_test(&dio->ref)) { - if (is_sync_kiocb(dio->iocb)) { + if (dio->wait_for_completion) { struct task_struct *waiter = dio->submit.waiter; - WRITE_ONCE(dio->submit.waiter, NULL); wake_up_process(waiter); } else if (dio->flags & IOMAP_DIO_WRITE) { @@ -1131,13 +1131,12 @@ iomap_dio_rw(struct kiocb *iocb, struct dio->end_io = end_io; dio->error = 0; dio->flags = 0; + dio->wait_for_completion = is_sync_kiocb(iocb); dio->submit.iter = iter; - if (is_sync_kiocb(iocb)) { - dio->submit.waiter = current; - dio->submit.cookie = BLK_QC_T_NONE; - dio->submit.last_queue = NULL; - } + dio->submit.waiter = current; + dio->submit.cookie = BLK_QC_T_NONE; + dio->submit.last_queue = NULL; if (iov_iter_rw(iter) == READ) { if (pos >= dio->i_size) @@ -1187,7 +1186,7 @@ iomap_dio_rw(struct kiocb *iocb, struct dio_warn_stale_pagecache(iocb->ki_filp); ret = 0; - if (iov_iter_rw(iter) == WRITE && !is_sync_kiocb(iocb) && + if (iov_iter_rw(iter) == WRITE && !dio->wait_for_completion && !inode->i_sb->s_dio_done_wq) { ret = sb_init_dio_done_wq(inode->i_sb); if (ret < 0) @@ -1202,8 +1201,10 @@ iomap_dio_rw(struct kiocb *iocb, struct iomap_dio_actor); if (ret <= 0) { /* magic error code to fall back to buffered I/O */ - if (ret == -ENOTBLK) + if (ret == -ENOTBLK) { + dio->wait_for_completion = true; ret = 0; + } break; } pos += ret; @@ -1224,7 +1225,7 @@ iomap_dio_rw(struct kiocb *iocb, struct dio->flags &= ~IOMAP_DIO_NEED_SYNC; if (!atomic_dec_and_test(&dio->ref)) { - if (!is_sync_kiocb(iocb)) + if (!dio->wait_for_completion) return -EIOCBQUEUED; for (;;) {