Received: by 2002:ac0:a582:0:0:0:0:0 with SMTP id m2-v6csp1346480imm; Tue, 2 Oct 2018 06:53:29 -0700 (PDT) X-Google-Smtp-Source: ACcGV63BKkRo1WZoEH1d2XZ/CyW3gT37Zp1RrYPtq9XjUMHBLB4S7zuYcvzfke82NAc5fG01Bin8 X-Received: by 2002:a17:902:3041:: with SMTP id u59-v6mr16607696plb.99.1538488409533; Tue, 02 Oct 2018 06:53:29 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1538488409; cv=none; d=google.com; s=arc-20160816; b=yx8j3bdG5TjDPYWtfaJqfz01CAkL0nYypG/unUbagFhFoHibUIUNoddvtuC8sD4njI EX0lLjehjcUv6RQeoEf+HfEj7LogVFaPMzM/q7IT0uyXWUaa/dSCcZlvkt2aX50g+5E4 DAJCgGtuoqJRkOlX+Sq5PngYZ40Ynh1+cKUN5kXgfk+boYAmxrRHa1A5UaVBdneCC1kx RPFMzY2YXrj8SDx8xbdlbDlNPYC0QrtbNkdzT7NLn1bZbgfPDr8Z4lUtFdpGrlTYMWMm sv68cTZG8zq1fUEt5sGdCthyfF/3e9eGuH4R38VnvY3i0vfjMZmRa9QEDGf9ReMsbAh0 0Vbw== 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=W7ZpYcJG34XK/as2uh+TwSnBQGz4eAnGyBt9Q63CjiI=; b=0uUdjmt4S/Ie/Kh+1rvUpFvrOkRbzQr5+YtjMYfgjl1xVYI/4vKu2ifs8FXz12w47j XANqhvSZFE9ADXakE6NjP9PDWWYEHmEuJt8ptr376vbqHQK2DfLBniHhp64+muVCP8PH PqTyGH/rN7ihZViI2Am+ihfkkP1XK7cpb4nRyiafj4l52btSatggbxcJ+gYAn9trcsCB 7LXHvq9lilp7OTIXmBCtms6E/d4yOeu5VrXRX2r0/VeDglPHDiz3R2SwCTKA+kCD5aui MZ02LatkW4FhkB/7qFYuXb/oBMzIq4vq5pR2m9ked3uwywzZmKkCBT185KYt6KoNB7q6 muZg== 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 s61-v6si15059180plb.125.2018.10.02.06.53.14; Tue, 02 Oct 2018 06:53:29 -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 S1731810AbeJBUQx (ORCPT + 99 others); Tue, 2 Oct 2018 16:16:53 -0400 Received: from mail.linuxfoundation.org ([140.211.169.12]:34902 "EHLO mail.linuxfoundation.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1730263AbeJBUQw (ORCPT ); Tue, 2 Oct 2018 16:16:52 -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 69F74BF0; Tue, 2 Oct 2018 13:33:28 +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.14 071/137] iomap: complete partial direct I/O writes synchronously Date: Tue, 2 Oct 2018 06:24:32 -0700 Message-Id: <20181002132503.551607066@linuxfoundation.org> X-Mailer: git-send-email 2.19.0 In-Reply-To: <20181002132458.446916963@linuxfoundation.org> References: <20181002132458.446916963@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.14-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 @@ -693,6 +693,7 @@ struct iomap_dio { atomic_t ref; unsigned flags; int error; + bool wait_for_completion; union { /* used during submission and for synchronous completion: */ @@ -793,9 +794,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) { @@ -980,13 +980,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) @@ -1016,7 +1015,7 @@ iomap_dio_rw(struct kiocb *iocb, struct WARN_ON_ONCE(ret); 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) @@ -1031,8 +1030,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; @@ -1046,7 +1047,7 @@ iomap_dio_rw(struct kiocb *iocb, struct iomap_dio_set_error(dio, ret); if (!atomic_dec_and_test(&dio->ref)) { - if (!is_sync_kiocb(iocb)) + if (!dio->wait_for_completion) return -EIOCBQUEUED; for (;;) {