xfs
[Top] [All Lists]

[PATCH 2/7] xfs: don't zero partial page cache pages during O_DIRECT wri

To: xfs@xxxxxxxxxxx
Subject: [PATCH 2/7] xfs: don't zero partial page cache pages during O_DIRECT writes
From: Dave Chinner <david@xxxxxxxxxxxxx>
Date: Thu, 28 Aug 2014 21:49:06 +1000
Delivered-to: xfs@xxxxxxxxxxx
In-reply-to: <1409226551-16570-1-git-send-email-david@xxxxxxxxxxxxx>
References: <1409226551-16570-1-git-send-email-david@xxxxxxxxxxxxx>
From: Chris Mason <clm@xxxxxx>

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.

[dchinner: catch error and warn if it fails. Comment.]

cc: stable@xxxxxxxxxxxxxxx
Signed-off-by: Chris Mason <clm@xxxxxx>
Reviewed-by: Dave Chinner <dchinner@xxxxxxxxxx>
Reviewed-by: Brian Foster <bfoster@xxxxxxxxxx>
Signed-off-by: Dave Chinner <david@xxxxxxxxxxxxx>
---
 fs/xfs/xfs_file.c | 11 ++++++++++-
 1 file changed, 10 insertions(+), 1 deletion(-)

diff --git a/fs/xfs/xfs_file.c b/fs/xfs/xfs_file.c
index 076b170..827cfb2 100644
--- a/fs/xfs/xfs_file.c
+++ b/fs/xfs/xfs_file.c
@@ -296,7 +296,16 @@ xfs_file_read_iter(
                                xfs_rw_iunlock(ip, XFS_IOLOCK_EXCL);
                                return ret;
                        }
-                       truncate_pagecache_range(VFS_I(ip), pos, -1);
+
+                       /*
+                        * Invalidate whole pages. This can return an error if
+                        * we fail to invalidate a page, but this should never
+                        * happen on XFS. Warn if it does fail.
+                        */
+                       ret = 
invalidate_inode_pages2_range(VFS_I(ip)->i_mapping,
+                                               pos >> PAGE_CACHE_SHIFT, -1);
+                       WARN_ON_ONCE(ret);
+                       ret = 0;
                }
                xfs_rw_ilock_demote(ip, XFS_IOLOCK_EXCL);
        }
-- 
2.0.0

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