[Top] [All Lists]

[PATCH v2] xfs: don't zero partial page cache pages during O_DIRECT

To: <xfs@xxxxxxxxxxx>, Dave Chinner <david@xxxxxxxxxxxxx>, Eric Sandeen <sandeen@xxxxxxxxxx>
Subject: [PATCH v2] xfs: don't zero partial page cache pages during O_DIRECT
From: Chris Mason <clm@xxxxxx>
Date: Sat, 9 Aug 2014 08:57:00 -0400
Delivered-to: xfs@xxxxxxxxxxx
Dkim-signature: v=1; a=rsa-sha256; c=relaxed/simple; d=fb.com; h=message-id : date : from : mime-version : to : subject : references : in-reply-to : content-type : content-transfer-encoding; s=facebook; bh=75hxKwQ5/n3j4J+3XG33qxOyNRPYxFr3huGp0daRMG0=; b=PuSuvS0leWl5zbOnp5uA26V2uRWevpzUyFjtYczWcoDHbvoEj6r8Z4KgR0IxM0wJXtms Q62XFQja2bxL8lHLQghAykoViuzkKoAvvKYcDu5im9KB3hgT1UNY78vyYN4sq9ekx4lb 4/aFJiX+7gwUUTSED0n6yg7oeVNdTRXpGp4=
In-reply-to: <53E4E03A.7050101@xxxxxx>
References: <53E4E03A.7050101@xxxxxx>
User-agent: Mozilla/5.0 (X11; Linux x86_64; rv:24.0) Gecko/20100101 Thunderbird/24.6.0
xfs is using truncate_pagecache_range to invalidate the page cache
during DIO reads.  This is different from the other filesystems who only
invalidate pages during DIO writes.

truncate_pagecache_range is meant to be used when we are freeing the
underlying data structs from disk, so it will zero any partial ranges in
the page.  This means a DIO read can zero out part of the page cache
page, and it is possible the page will stay in cache.

buffered reads will find an up to date page with zeros instead of the
data actually on disk.

This patch fixes things by using invalidate_inode_pages2_range instead.
It preserves the page cache invalidation, but won't zero any pages.

Signed-off-by: Chris Mason <clm@xxxxxx>
cc: stable@xxxxxxxxxxxxxxx

 fs/xfs/xfs_file.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/fs/xfs/xfs_file.c b/fs/xfs/xfs_file.c
index 1f66779..023d575 100644
--- a/fs/xfs/xfs_file.c
+++ b/fs/xfs/xfs_file.c
@@ -295,7 +295,8 @@ xfs_file_read_iter(
                                xfs_rw_iunlock(ip, XFS_IOLOCK_EXCL);
                                return ret;
-                       truncate_pagecache_range(VFS_I(ip), pos, -1);
+                       invalidate_inode_pages2_range(VFS_I(ip)->i_mapping,
+                                             pos >> PAGE_CACHE_SHIFT, -1);
                xfs_rw_ilock_demote(ip, XFS_IOLOCK_EXCL);

<Prev in Thread] Current Thread [Next in Thread>