Skip to content

Commit 4f62293

Browse files
jankaraRoss Zwisler
authored andcommitted
dax: Allow DAX code to replace exceptional entries
Currently we forbid page_cache_tree_insert() to replace exceptional radix tree entries for DAX inodes. However to make DAX faults race free we will lock radix tree entries and when hole is created, we need to replace such locked radix tree entry with a hole page. So modify page_cache_tree_insert() to allow that. Reviewed-by: Ross Zwisler <[email protected]> Signed-off-by: Jan Kara <[email protected]> Signed-off-by: Ross Zwisler <[email protected]>
1 parent e804315 commit 4f62293

File tree

2 files changed

+15
-7
lines changed

2 files changed

+15
-7
lines changed

include/linux/dax.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33

44
#include <linux/fs.h>
55
#include <linux/mm.h>
6+
#include <linux/radix-tree.h>
67
#include <asm/pgtable.h>
78

89
/* We use lowest available exceptional entry bit for locking */

mm/filemap.c

Lines changed: 14 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -597,14 +597,21 @@ static int page_cache_tree_insert(struct address_space *mapping,
597597
if (!radix_tree_exceptional_entry(p))
598598
return -EEXIST;
599599

600-
if (WARN_ON(dax_mapping(mapping)))
601-
return -EINVAL;
602-
603-
if (shadowp)
604-
*shadowp = p;
605600
mapping->nrexceptional--;
606-
if (node)
607-
workingset_node_shadows_dec(node);
601+
if (!dax_mapping(mapping)) {
602+
if (shadowp)
603+
*shadowp = p;
604+
if (node)
605+
workingset_node_shadows_dec(node);
606+
} else {
607+
/* DAX can replace empty locked entry with a hole */
608+
WARN_ON_ONCE(p !=
609+
(void *)(RADIX_TREE_EXCEPTIONAL_ENTRY |
610+
RADIX_DAX_ENTRY_LOCK));
611+
/* DAX accounts exceptional entries as normal pages */
612+
if (node)
613+
workingset_node_pages_dec(node);
614+
}
608615
}
609616
radix_tree_replace_slot(slot, page);
610617
mapping->nrpages++;

0 commit comments

Comments
 (0)