[Devel] [PATCH rh7] fs/cleancache: fix data invalidation in the cleancache during direct_io
Andrey Ryabinin
aryabinin at virtuozzo.com
Wed Apr 12 08:53:18 PDT 2017
On 04/12/2017 05:45 PM, Andrey Ryabinin wrote:
> On 04/11/2017 08:08 PM, Alexey Kuznetsov wrote:
>> Hello!
>>
>> Good job!
>>
>> Before submitting this to mainstream look
>> at truncate_inode_pages.
>>
>> It has condition:
>>
>> if (mapping->nrpages == 0 && mapping->nrexceptional == 0)
>> return;
>>
>> I have no idea what are those exceptions are, but it definitely
>> looks illegal to check only for nrpages in invalidate_inode_pages2_range,
>> it clears exceptional entries as well.
>>
>
> AFAIU exceptional entries are either dax entires, they store sector number and
> entry size (PMD, PTE,...), or they used by workingset code to store some information
> about page eviction.
>
> Given that, invalidate_inode_pages2_range() supposed to invalidate stale data in page
> cache/cleancache (per my understanding at least) I would say that invalidate_inode_pages2_range()
> shouldn't remove exceptional entries. But not sure that my understanding is correct,
> so I'm going to add ->nrexceptional check in v2, but will ask about this ambiguousity
> upstream folks.
>
Just for easier review, this is diff between v1 and v2:
---
fs/xfs/xfs_file.c | 14 ++++++--------
mm/truncate.c | 2 +-
2 files changed, 7 insertions(+), 9 deletions(-)
diff --git a/fs/xfs/xfs_file.c b/fs/xfs/xfs_file.c
index d758443..0b7a35b 100644
--- a/fs/xfs/xfs_file.c
+++ b/fs/xfs/xfs_file.c
@@ -346,7 +346,7 @@ xfs_file_aio_read(
* serialisation.
*/
xfs_rw_ilock(ip, XFS_IOLOCK_SHARED);
- if ((ioflags & XFS_IO_ISDIRECT) && inode->i_mapping->nrpages) {
+ if ((ioflags & XFS_IO_ISDIRECT)) {
xfs_rw_iunlock(ip, XFS_IOLOCK_SHARED);
xfs_rw_ilock(ip, XFS_IOLOCK_EXCL);
@@ -361,14 +361,12 @@ xfs_file_aio_read(
* flush and reduce the chances of repeated iolock cycles going
* forward.
*/
- if (inode->i_mapping->nrpages) {
- ret = filemap_write_and_wait(VFS_I(ip)->i_mapping);
- if (ret) {
- xfs_rw_iunlock(ip, XFS_IOLOCK_EXCL);
- return ret;
- }
-
+ ret = filemap_write_and_wait(VFS_I(ip)->i_mapping);
+ if (ret) {
+ xfs_rw_iunlock(ip, XFS_IOLOCK_EXCL);
+ return ret;
}
+
/*
* Invalidate whole pages. This can return an error if
* we fail to invalidate a page, but this should never
diff --git a/mm/truncate.c b/mm/truncate.c
index f015a86..ce4b1d8 100644
--- a/mm/truncate.c
+++ b/mm/truncate.c
@@ -629,7 +629,7 @@ int invalidate_inode_pages2_range(struct address_space *mapping,
cleancache_invalidate_inode(mapping);
- if (mapping->nrpages == 0)
+ if (mapping->nrpages == 0 && mapping->nrexceptional == 0)
return 0;
pagevec_init(&pvec, 0);
--
2.10.2
More information about the Devel
mailing list