From patchwork Sat Nov 2 13:12:58 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Konstantin Khlebnikov X-Patchwork-Id: 11224091 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 06FDA14E5 for ; Sat, 2 Nov 2019 13:13:09 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id D8FB021726 for ; Sat, 2 Nov 2019 13:13:08 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (1024-bit key) header.d=yandex-team.ru header.i=@yandex-team.ru header.b="nVYU5bX0" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726437AbfKBNNE (ORCPT ); Sat, 2 Nov 2019 09:13:04 -0400 Received: from forwardcorp1o.mail.yandex.net ([95.108.205.193]:33616 "EHLO forwardcorp1o.mail.yandex.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726329AbfKBNNE (ORCPT ); Sat, 2 Nov 2019 09:13:04 -0400 Received: from mxbackcorp1g.mail.yandex.net (mxbackcorp1g.mail.yandex.net [IPv6:2a02:6b8:0:1402::301]) by forwardcorp1o.mail.yandex.net (Yandex) with ESMTP id 86E512E1448; Sat, 2 Nov 2019 16:13:00 +0300 (MSK) Received: from sas1-7fab0cd91cd2.qloud-c.yandex.net (sas1-7fab0cd91cd2.qloud-c.yandex.net [2a02:6b8:c14:3a93:0:640:7fab:cd9]) by mxbackcorp1g.mail.yandex.net (nwsmtp/Yandex) with ESMTP id WfxxPXTLLl-CxDGRls1; Sat, 02 Nov 2019 16:13:00 +0300 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=yandex-team.ru; s=default; t=1572700380; bh=GjZu/WoaF6tLkOYo8V/8/nxWXOX7M22Xey9THKkbDAg=; h=Message-ID:Date:To:From:Subject:Cc; b=nVYU5bX0BbcH6zHWDjqI/XmQO+CTu5XFgYSDvYlaAwo5vYPo0aOqkVigo7zamEC8Y EDDPzBGPap5oVpPYgXsfWXspAcqIfcl68YrX3o5oop+q/ZiGweb7Q5rmvOb6LLzlOY g1AJ1NPneLX5yh9imdgFt3qWuUzGxQeCMDsce4+M= Authentication-Results: mxbackcorp1g.mail.yandex.net; dkim=pass header.i=@yandex-team.ru Received: from dynamic-red.dhcp.yndx.net (dynamic-red.dhcp.yndx.net [2a02:6b8:0:40c:8554:53c0:3d75:2e8a]) by sas1-7fab0cd91cd2.qloud-c.yandex.net (nwsmtp/Yandex) with ESMTPSA id 2QDPdOoyS9-CxWep5NX; Sat, 02 Nov 2019 16:12:59 +0300 (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (Client certificate not present) Subject: [PATCH v2 1/3] fs: remove redundant cache invalidation after async direct-io write From: Konstantin Khlebnikov To: linux-mm@kvack.org, Andrew Morton , linux-kernel@vger.kernel.org Cc: linux-fsdevel@vger.kernel.org, Jens Axboe , Jan Kara , Alexander Viro Date: Sat, 02 Nov 2019 16:12:58 +0300 Message-ID: <157270037850.4812.15036239021726025572.stgit@buzz> User-Agent: StGit/0.17.1-dirty MIME-Version: 1.0 Sender: linux-fsdevel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-fsdevel@vger.kernel.org Function generic_file_direct_write() invalidates cache at entry. Second time this should be done when request completes. But this function calls second invalidation at exit unconditionally even for async requests. This patch skips second invalidation for async requests (-EIOCBQUEUED). Signed-off-by: Konstantin Khlebnikov Reviewed-by: Jan Kara --- mm/filemap.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/mm/filemap.c b/mm/filemap.c index 85b7d087eb45..288e38199068 100644 --- a/mm/filemap.c +++ b/mm/filemap.c @@ -3218,9 +3218,11 @@ generic_file_direct_write(struct kiocb *iocb, struct iov_iter *from) * Most of the time we do not need this since dio_complete() will do * the invalidation for us. However there are some file systems that * do not end up with dio_complete() being called, so let's not break - * them by removing it completely + * them by removing it completely. + * + * Skip invalidation for async writes or if mapping has no pages. */ - if (mapping->nrpages) + if (written > 0 && mapping->nrpages) invalidate_inode_pages2_range(mapping, pos >> PAGE_SHIFT, end); From patchwork Sat Nov 2 13:13:00 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Konstantin Khlebnikov X-Patchwork-Id: 11224095 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 31481139A for ; Sat, 2 Nov 2019 13:13:09 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 101F521726 for ; Sat, 2 Nov 2019 13:13:09 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (1024-bit key) header.d=yandex-team.ru header.i=@yandex-team.ru header.b="BfwjJO9A" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726749AbfKBNNF (ORCPT ); Sat, 2 Nov 2019 09:13:05 -0400 Received: from forwardcorp1o.mail.yandex.net ([95.108.205.193]:33668 "EHLO forwardcorp1o.mail.yandex.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726380AbfKBNNE (ORCPT ); Sat, 2 Nov 2019 09:13:04 -0400 Received: from mxbackcorp2j.mail.yandex.net (mxbackcorp2j.mail.yandex.net [IPv6:2a02:6b8:0:1619::119]) by forwardcorp1o.mail.yandex.net (Yandex) with ESMTP id BE43E2E144E; Sat, 2 Nov 2019 16:13:02 +0300 (MSK) Received: from sas1-7fab0cd91cd2.qloud-c.yandex.net (sas1-7fab0cd91cd2.qloud-c.yandex.net [2a02:6b8:c14:3a93:0:640:7fab:cd9]) by mxbackcorp2j.mail.yandex.net (nwsmtp/Yandex) with ESMTP id IqdqyEa08e-D10WsN1u; Sat, 02 Nov 2019 16:13:02 +0300 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=yandex-team.ru; s=default; t=1572700382; bh=S/T/iL7jEJxMwyZ59MfWBFPCGwDwwzXkT2FcFTKPCc4=; h=In-Reply-To:Message-ID:References:Date:To:From:Subject:Cc; b=BfwjJO9Ao/nI9ks9slEwlWMFLlqzytlHEsrFjK63anNbSeKq7Ao5Q6zjdDXYhvyVc f7BS4RSgIwyPpGxKJ0D8lsW8PxpSjQmLqfU4Ie4ZFSaqXQ3M+yBInfffwOxjSbFuLE WYyITwJ2TECD7VcHIQNde3wTja4QNmcSvgEFpKg8= Authentication-Results: mxbackcorp2j.mail.yandex.net; dkim=pass header.i=@yandex-team.ru Received: from dynamic-red.dhcp.yndx.net (dynamic-red.dhcp.yndx.net [2a02:6b8:0:40c:8554:53c0:3d75:2e8a]) by sas1-7fab0cd91cd2.qloud-c.yandex.net (nwsmtp/Yandex) with ESMTPSA id ZXpOk2889Z-D1WiJTEg; Sat, 02 Nov 2019 16:13:01 +0300 (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (Client certificate not present) Subject: [PATCH v2 2/3] fs: keep dio_warn_stale_pagecache() when CONFIG_BLOCK=n From: Konstantin Khlebnikov To: linux-mm@kvack.org, Andrew Morton , linux-kernel@vger.kernel.org Cc: linux-fsdevel@vger.kernel.org, Jens Axboe , Jan Kara , Alexander Viro Date: Sat, 02 Nov 2019 16:13:00 +0300 Message-ID: <157270038074.4812.7980855544557488880.stgit@buzz> In-Reply-To: <157270037850.4812.15036239021726025572.stgit@buzz> References: <157270037850.4812.15036239021726025572.stgit@buzz> User-Agent: StGit/0.17.1-dirty MIME-Version: 1.0 Sender: linux-fsdevel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-fsdevel@vger.kernel.org This helper prints warning if direct I/O write failed to invalidate cache, and set EIO at inode to warn usersapce about possible data corruption. See also commit 5a9d929d6e13 ("iomap: report collisions between directio and buffered writes to userspace"). Direct I/O is supported by non-disk filesystems, for example NFS. Thus generic code needs this even in kernel without CONFIG_BLOCK. Signed-off-by: Konstantin Khlebnikov Reviewed-by: Jan Kara --- fs/direct-io.c | 21 --------------------- include/linux/fs.h | 6 +++++- mm/filemap.c | 21 +++++++++++++++++++++ 3 files changed, 26 insertions(+), 22 deletions(-) diff --git a/fs/direct-io.c b/fs/direct-io.c index 9329ced91f1d..0ec4f270139f 100644 --- a/fs/direct-io.c +++ b/fs/direct-io.c @@ -220,27 +220,6 @@ static inline struct page *dio_get_page(struct dio *dio, return dio->pages[sdio->head]; } -/* - * Warn about a page cache invalidation failure during a direct io write. - */ -void dio_warn_stale_pagecache(struct file *filp) -{ - static DEFINE_RATELIMIT_STATE(_rs, 86400 * HZ, DEFAULT_RATELIMIT_BURST); - char pathname[128]; - struct inode *inode = file_inode(filp); - char *path; - - errseq_set(&inode->i_mapping->wb_err, -EIO); - if (__ratelimit(&_rs)) { - path = file_path(filp, pathname, sizeof(pathname)); - if (IS_ERR(path)) - path = "(unknown)"; - pr_crit("Page cache invalidation failure on direct I/O. Possible data corruption due to collision with buffered I/O!\n"); - pr_crit("File: %s PID: %d Comm: %.20s\n", path, current->pid, - current->comm); - } -} - /* * dio_complete() - called when all DIO BIO I/O has been completed * diff --git a/include/linux/fs.h b/include/linux/fs.h index e0d909d35763..b4e4560d1c38 100644 --- a/include/linux/fs.h +++ b/include/linux/fs.h @@ -3153,7 +3153,6 @@ enum { }; void dio_end_io(struct bio *bio); -void dio_warn_stale_pagecache(struct file *filp); ssize_t __blockdev_direct_IO(struct kiocb *iocb, struct inode *inode, struct block_device *bdev, struct iov_iter *iter, @@ -3198,6 +3197,11 @@ static inline void inode_dio_end(struct inode *inode) wake_up_bit(&inode->i_state, __I_DIO_WAKEUP); } +/* + * Warn about a page cache invalidation failure diring a direct I/O write. + */ +void dio_warn_stale_pagecache(struct file *filp); + extern void inode_set_flags(struct inode *inode, unsigned int flags, unsigned int mask); diff --git a/mm/filemap.c b/mm/filemap.c index 288e38199068..189b8f318da2 100644 --- a/mm/filemap.c +++ b/mm/filemap.c @@ -3161,6 +3161,27 @@ int pagecache_write_end(struct file *file, struct address_space *mapping, } EXPORT_SYMBOL(pagecache_write_end); +/* + * Warn about a page cache invalidation failure during a direct I/O write. + */ +void dio_warn_stale_pagecache(struct file *filp) +{ + static DEFINE_RATELIMIT_STATE(_rs, 86400 * HZ, DEFAULT_RATELIMIT_BURST); + char pathname[128]; + struct inode *inode = file_inode(filp); + char *path; + + errseq_set(&inode->i_mapping->wb_err, -EIO); + if (__ratelimit(&_rs)) { + path = file_path(filp, pathname, sizeof(pathname)); + if (IS_ERR(path)) + path = "(unknown)"; + pr_crit("Page cache invalidation failure on direct I/O. Possible data corruption due to collision with buffered I/O!\n"); + pr_crit("File: %s PID: %d Comm: %.20s\n", path, current->pid, + current->comm); + } +} + ssize_t generic_file_direct_write(struct kiocb *iocb, struct iov_iter *from) { From patchwork Sat Nov 2 13:13:03 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Konstantin Khlebnikov X-Patchwork-Id: 11224099 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 D272314E5 for ; Sat, 2 Nov 2019 13:13:28 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id B15C721D80 for ; Sat, 2 Nov 2019 13:13:28 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (1024-bit key) header.d=yandex-team.ru header.i=@yandex-team.ru header.b="OxUUATt2" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726907AbfKBNNI (ORCPT ); Sat, 2 Nov 2019 09:13:08 -0400 Received: from forwardcorp1p.mail.yandex.net ([77.88.29.217]:56690 "EHLO forwardcorp1p.mail.yandex.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726380AbfKBNNH (ORCPT ); Sat, 2 Nov 2019 09:13:07 -0400 Received: from mxbackcorp1o.mail.yandex.net (mxbackcorp1o.mail.yandex.net [IPv6:2a02:6b8:0:1a2d::301]) by forwardcorp1p.mail.yandex.net (Yandex) with ESMTP id 642102E099D; Sat, 2 Nov 2019 16:13:05 +0300 (MSK) Received: from iva4-c987840161f8.qloud-c.yandex.net (iva4-c987840161f8.qloud-c.yandex.net [2a02:6b8:c0c:3da5:0:640:c987:8401]) by mxbackcorp1o.mail.yandex.net (nwsmtp/Yandex) with ESMTP id o44VC5sfra-D4juUgbU; Sat, 02 Nov 2019 16:13:05 +0300 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=yandex-team.ru; s=default; t=1572700385; bh=H7FmyTVkpiw9VXplqlyRxQrERQupmOL/uyKSLjwdIdg=; h=In-Reply-To:Message-ID:References:Date:To:From:Subject:Cc; b=OxUUATt2MW6cMx8NEijyWMs0vDxqyGl9Hu5nQSsfhVkprtv1/Uv5n1WLtyT/WW5hL oPYbwCOT+g28r8eaffciKLzmSqkXrHs4WcMOKNUQLBFbTteXGYUs5zkdobEY6yi0GZ 4oF+DIH/CFEoJDGPesZ7+RmfP7TAE9OO2iza5z3g= Authentication-Results: mxbackcorp1o.mail.yandex.net; dkim=pass header.i=@yandex-team.ru Received: from dynamic-red.dhcp.yndx.net (dynamic-red.dhcp.yndx.net [2a02:6b8:0:40c:8554:53c0:3d75:2e8a]) by iva4-c987840161f8.qloud-c.yandex.net (nwsmtp/Yandex) with ESMTPSA id lWH2NgOfEQ-D4VWcMj0; Sat, 02 Nov 2019 16:13:04 +0300 (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (Client certificate not present) Subject: [PATCH v2 3/3] fs: warn if stale pagecache is left after direct write From: Konstantin Khlebnikov To: linux-mm@kvack.org, Andrew Morton , linux-kernel@vger.kernel.org Cc: linux-fsdevel@vger.kernel.org, Jens Axboe , Jan Kara , Alexander Viro Date: Sat, 02 Nov 2019 16:13:03 +0300 Message-ID: <157270038294.4812.2238891109785106069.stgit@buzz> In-Reply-To: <157270037850.4812.15036239021726025572.stgit@buzz> References: <157270037850.4812.15036239021726025572.stgit@buzz> User-Agent: StGit/0.17.1-dirty MIME-Version: 1.0 Sender: linux-fsdevel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-fsdevel@vger.kernel.org Function generic_file_direct_write() tries to invalidate pagecache after O_DIRECT write. Unlike to similar code in dio_complete() this silently ignores error returned from invalidate_inode_pages2_range(). According to comment this code here because not all filesystems call dio_complete() to do proper invalidation after O_DIRECT write. Noticeable example is a blkdev_direct_IO(). This patch calls dio_warn_stale_pagecache() if invalidation fails. Signed-off-by: Konstantin Khlebnikov Reviewed-by: Jan Kara --- mm/filemap.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/mm/filemap.c b/mm/filemap.c index 189b8f318da2..dc3b78db079b 100644 --- a/mm/filemap.c +++ b/mm/filemap.c @@ -3241,11 +3241,13 @@ generic_file_direct_write(struct kiocb *iocb, struct iov_iter *from) * do not end up with dio_complete() being called, so let's not break * them by removing it completely. * + * Noticeable example is a blkdev_direct_IO(). + * * Skip invalidation for async writes or if mapping has no pages. */ - if (written > 0 && mapping->nrpages) - invalidate_inode_pages2_range(mapping, - pos >> PAGE_SHIFT, end); + if (written > 0 && mapping->nrpages && + invalidate_inode_pages2_range(mapping, pos >> PAGE_SHIFT, end)) + dio_warn_stale_pagecache(file); if (written > 0) { pos += written;