From patchwork Sun Sep 20 23:48:52 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Gabriel Krisman Bertazi X-Patchwork-Id: 11788173 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 3D23A59D for ; Sun, 20 Sep 2020 23:49:11 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 2DD0120874 for ; Sun, 20 Sep 2020 23:49:11 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726253AbgITXtK (ORCPT ); Sun, 20 Sep 2020 19:49:10 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:46994 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726156AbgITXtK (ORCPT ); Sun, 20 Sep 2020 19:49:10 -0400 Received: from bhuna.collabora.co.uk (bhuna.collabora.co.uk [IPv6:2a00:1098:0:82:1000:25:2eeb:e3e3]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 7221AC061755 for ; Sun, 20 Sep 2020 16:49:10 -0700 (PDT) Received: from [127.0.0.1] (localhost [127.0.0.1]) (Authenticated sender: krisman) with ESMTPSA id 0636E294F70 From: Gabriel Krisman Bertazi To: viro@zeniv.linux.org.uk Cc: linux-fsdevel@vger.kernel.org, Gabriel Krisman Bertazi , kernel@collabora.com, Jan Kara Subject: [PATCH RESEND v3 1/3] direct-io: clean up error paths of do_blockdev_direct_IO Date: Sun, 20 Sep 2020 19:48:52 -0400 Message-Id: <20200920234854.4175918-2-krisman@collabora.com> X-Mailer: git-send-email 2.28.0 In-Reply-To: <20200920234854.4175918-1-krisman@collabora.com> References: <20200920234854.4175918-1-krisman@collabora.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-fsdevel@vger.kernel.org In preparation to resort DIO checks, reduce code duplication of error handling in do_blockdev_direct_IO. Reviewed-by: Jan Kara Signed-off-by: Gabriel Krisman Bertazi --- fs/direct-io.c | 35 ++++++++++++++--------------------- 1 file changed, 14 insertions(+), 21 deletions(-) diff --git a/fs/direct-io.c b/fs/direct-io.c index 183299892465..6c11db1cec27 100644 --- a/fs/direct-io.c +++ b/fs/direct-io.c @@ -1170,7 +1170,7 @@ do_blockdev_direct_IO(struct kiocb *iocb, struct inode *inode, blkbits = blksize_bits(bdev_logical_block_size(bdev)); blocksize_mask = (1 << blkbits) - 1; if (align & blocksize_mask) - goto out; + return -EINVAL; } /* watch out for a 0 len io from a tricksy fs */ @@ -1178,9 +1178,8 @@ do_blockdev_direct_IO(struct kiocb *iocb, struct inode *inode, return 0; dio = kmem_cache_alloc(dio_cache, GFP_KERNEL); - retval = -ENOMEM; if (!dio) - goto out; + return -ENOMEM; /* * Believe it or not, zeroing out the page array caused a .5% * performance regression in a database benchmark. So, we take @@ -1199,22 +1198,16 @@ do_blockdev_direct_IO(struct kiocb *iocb, struct inode *inode, retval = filemap_write_and_wait_range(mapping, offset, end - 1); - if (retval) { - inode_unlock(inode); - kmem_cache_free(dio_cache, dio); - goto out; - } + if (retval) + goto fail_dio; } } /* Once we sampled i_size check for reads beyond EOF */ dio->i_size = i_size_read(inode); if (iov_iter_rw(iter) == READ && offset >= dio->i_size) { - if (dio->flags & DIO_LOCKING) - inode_unlock(inode); - kmem_cache_free(dio_cache, dio); retval = 0; - goto out; + goto fail_dio; } /* @@ -1258,14 +1251,8 @@ do_blockdev_direct_IO(struct kiocb *iocb, struct inode *inode, */ retval = sb_init_dio_done_wq(dio->inode->i_sb); } - if (retval) { - /* - * We grab i_mutex only for reads so we don't have - * to release it here - */ - kmem_cache_free(dio_cache, dio); - goto out; - } + if (retval) + goto fail_dio; } /* @@ -1368,7 +1355,13 @@ do_blockdev_direct_IO(struct kiocb *iocb, struct inode *inode, } else BUG_ON(retval != -EIOCBQUEUED); -out: + return retval; + +fail_dio: + if (dio->flags & DIO_LOCKING && iov_iter_rw(iter) == READ) + inode_unlock(inode); + + kmem_cache_free(dio_cache, dio); return retval; } From patchwork Sun Sep 20 23:48:53 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Gabriel Krisman Bertazi X-Patchwork-Id: 11788175 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 9C41D6CB for ; Sun, 20 Sep 2020 23:49:15 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 820CD20809 for ; Sun, 20 Sep 2020 23:49:15 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726267AbgITXtP (ORCPT ); Sun, 20 Sep 2020 19:49:15 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:47010 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726156AbgITXtO (ORCPT ); Sun, 20 Sep 2020 19:49:14 -0400 Received: from bhuna.collabora.co.uk (bhuna.collabora.co.uk [IPv6:2a00:1098:0:82:1000:25:2eeb:e3e3]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id C16D9C061755 for ; Sun, 20 Sep 2020 16:49:14 -0700 (PDT) Received: from [127.0.0.1] (localhost [127.0.0.1]) (Authenticated sender: krisman) with ESMTPSA id 99046297AB3 From: Gabriel Krisman Bertazi To: viro@zeniv.linux.org.uk Cc: linux-fsdevel@vger.kernel.org, Gabriel Krisman Bertazi , kernel@collabora.com, Jan Kara Subject: [PATCH RESEND v3 2/3] direct-io: don't force writeback for reads beyond EOF Date: Sun, 20 Sep 2020 19:48:53 -0400 Message-Id: <20200920234854.4175918-3-krisman@collabora.com> X-Mailer: git-send-email 2.28.0 In-Reply-To: <20200920234854.4175918-1-krisman@collabora.com> References: <20200920234854.4175918-1-krisman@collabora.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-fsdevel@vger.kernel.org If a DIO read starts past EOF, the kernel won't attempt it, so we don't need to flush dirty pages before failing the syscall. Suggested-by: Jan Kara Reviewed-by: Jan Kara Signed-off-by: Gabriel Krisman Bertazi --- fs/direct-io.c | 24 +++++++++++------------- 1 file changed, 11 insertions(+), 13 deletions(-) diff --git a/fs/direct-io.c b/fs/direct-io.c index 6c11db1cec27..c17efe58f1c9 100644 --- a/fs/direct-io.c +++ b/fs/direct-io.c @@ -1188,19 +1188,9 @@ do_blockdev_direct_IO(struct kiocb *iocb, struct inode *inode, memset(dio, 0, offsetof(struct dio, pages)); dio->flags = flags; - if (dio->flags & DIO_LOCKING) { - if (iov_iter_rw(iter) == READ) { - struct address_space *mapping = - iocb->ki_filp->f_mapping; - - /* will be released by direct_io_worker */ - inode_lock(inode); - - retval = filemap_write_and_wait_range(mapping, offset, - end - 1); - if (retval) - goto fail_dio; - } + if (dio->flags & DIO_LOCKING && iov_iter_rw(iter) == READ) { + /* will be released by direct_io_worker */ + inode_lock(inode); } /* Once we sampled i_size check for reads beyond EOF */ @@ -1210,6 +1200,14 @@ do_blockdev_direct_IO(struct kiocb *iocb, struct inode *inode, goto fail_dio; } + if (dio->flags & DIO_LOCKING && iov_iter_rw(iter) == READ) { + struct address_space *mapping = iocb->ki_filp->f_mapping; + + retval = filemap_write_and_wait_range(mapping, offset, end - 1); + if (retval) + goto fail_dio; + } + /* * For file extending writes updating i_size before data writeouts * complete can expose uninitialized blocks in dumb filesystems. From patchwork Sun Sep 20 23:48:54 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Gabriel Krisman Bertazi X-Patchwork-Id: 11788177 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 9A0F959D for ; Sun, 20 Sep 2020 23:49:19 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 7F33C20809 for ; Sun, 20 Sep 2020 23:49:19 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726315AbgITXtT (ORCPT ); Sun, 20 Sep 2020 19:49:19 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:47022 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726156AbgITXtS (ORCPT ); Sun, 20 Sep 2020 19:49:18 -0400 Received: from bhuna.collabora.co.uk (bhuna.collabora.co.uk [IPv6:2a00:1098:0:82:1000:25:2eeb:e3e3]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id CA5B5C061755 for ; Sun, 20 Sep 2020 16:49:18 -0700 (PDT) Received: from [127.0.0.1] (localhost [127.0.0.1]) (Authenticated sender: krisman) with ESMTPSA id 78649297AAF From: Gabriel Krisman Bertazi To: viro@zeniv.linux.org.uk Cc: linux-fsdevel@vger.kernel.org, Gabriel Krisman Bertazi , kernel@collabora.com, Jamie Liu , Jan Kara Subject: [PATCH RESEND v3 3/3] direct-io: defer alignment check until after the EOF check Date: Sun, 20 Sep 2020 19:48:54 -0400 Message-Id: <20200920234854.4175918-4-krisman@collabora.com> X-Mailer: git-send-email 2.28.0 In-Reply-To: <20200920234854.4175918-1-krisman@collabora.com> References: <20200920234854.4175918-1-krisman@collabora.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-fsdevel@vger.kernel.org Prior to commit 9fe55eea7e4b ("Fix race when checking i_size on direct i/o read"), an unaligned direct read past end of file would trigger EOF, since generic_file_aio_read detected this read-at-EOF condition and skipped the direct IO read entirely, returning 0. After that change, the read now reaches dio_generic, which detects the misalignment and returns EINVAL. This consolidates the generic direct-io to follow the same behavior of filesystems. Apparently, this fix will only affect ocfs2 since other filesystems do this verification before calling do_blockdev_direct_IO, with the exception of f2fs, which has the same bug, but is fixed in the next patch. it can be verified by a read loop on a file that does a partial read before EOF (On file that doesn't end at an aligned address). The following code fails on an unaligned file on filesystems without prior validation without this patch, but not on btrfs, ext4, and xfs. while (done < total) { ssize_t delta = pread(fd, buf + done, total - done, off + done); if (!delta) break; ... } Fix this regression by moving the misalignment check to after the EOF check added by commit 74cedf9b6c60 ("direct-io: Fix negative return from dio read beyond eof"). Based on a patch by Jamie Liu. Reported-by: Jamie Liu Reviewed-by: Jan Kara Signed-off-by: Gabriel Krisman Bertazi --- fs/direct-io.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/fs/direct-io.c b/fs/direct-io.c index c17efe58f1c9..82838cca934b 100644 --- a/fs/direct-io.c +++ b/fs/direct-io.c @@ -1165,14 +1165,6 @@ do_blockdev_direct_IO(struct kiocb *iocb, struct inode *inode, * the early prefetch in the caller enough time. */ - if (align & blocksize_mask) { - if (bdev) - blkbits = blksize_bits(bdev_logical_block_size(bdev)); - blocksize_mask = (1 << blkbits) - 1; - if (align & blocksize_mask) - return -EINVAL; - } - /* watch out for a 0 len io from a tricksy fs */ if (iov_iter_rw(iter) == READ && !count) return 0; @@ -1200,6 +1192,14 @@ do_blockdev_direct_IO(struct kiocb *iocb, struct inode *inode, goto fail_dio; } + if (align & blocksize_mask) { + if (bdev) + blkbits = blksize_bits(bdev_logical_block_size(bdev)); + blocksize_mask = (1 << blkbits) - 1; + if (align & blocksize_mask) + goto fail_dio; + } + if (dio->flags & DIO_LOCKING && iov_iter_rw(iter) == READ) { struct address_space *mapping = iocb->ki_filp->f_mapping;