• Jan Kara's avatar
    dax: fix ENOMEM handling in grab_mapping_entry() · 1a14e377
    Jan Kara authored
    grab_mapping_entry() has a bug in handling of ENOMEM condition.  Suppose
    we have a PMD entry at index i which we are downgrading to a PTE entry.
    grab_mapping_entry() will set pmd_downgrade to true, lock the entry, clear
    the entry in xarray, and decrement mapping->nrpages.  The it will call:
    
    	entry = dax_make_entry(pfn_to_pfn_t(0), flags);
    	dax_lock_entry(xas, entry);
    
    which inserts new PTE entry into xarray.  However this may fail allocating
    the new node.  We handle this by:
    
    	if (xas_nomem(xas, mapping_gfp_mask(mapping) & ~__GFP_HIGHMEM))
    		goto retry;
    
    however pmd_downgrade stays set to true even though 'entry' returned from
    get_unlocked_entry() will be NULL now.  And we will go again through the
    downgrade branch.  This is mostly harmless except that mapping->nrpages is
    decremented again and we temporarily have an invalid entry stored in
    xarray.  Fix the problem by setting pmd_downgrade to false each time we
    lookup the entry we work with so that it matches the entry we found.
    
    Link: https://lkml.kernel.org/r/20210622160015.18004-1-jack@suse.cz
    Fixes: b15cd800 ("dax: Convert page fault handlers to XArray")
    Signed-off-by: default avatarJan Kara <jack@suse.cz>
    Reviewed-by: default avatarDan Williams <dan.j.williams@intel.com>
    Cc: Matthew Wilcox <willy@infradead.org>
    Cc: "Aneesh Kumar K.V" <aneesh.kumar@linux.ibm.com>
    Signed-off-by: default avatarAndrew Morton <akpm@linux-foundation.org>
    Signed-off-by: default avatarLinus Torvalds <torvalds@linux-foundation.org>
    1a14e377
dax.c 46.7 KB