• Ross Zwisler's avatar
    dax: wrprotect pmd_t in dax_mapping_entry_mkclean · f729c8c9
    Ross Zwisler authored
    Currently dax_mapping_entry_mkclean() fails to clean and write protect
    the pmd_t of a DAX PMD entry during an *sync operation.  This can result
    in data loss in the following sequence:
    
    1) mmap write to DAX PMD, dirtying PMD radix tree entry and making the
       pmd_t dirty and writeable
    2) fsync, flushing out PMD data and cleaning the radix tree entry. We
       currently fail to mark the pmd_t as clean and write protected.
    3) more mmap writes to the PMD.  These don't cause any page faults since
       the pmd_t is dirty and writeable.  The radix tree entry remains clean.
    4) fsync, which fails to flush the dirty PMD data because the radix tree
       entry was clean.
    5) crash - dirty data that should have been fsync'd as part of 4) could
       still have been in the processor cache, and is lost.
    
    Fix this by marking the pmd_t clean and write protected in
    dax_mapping_entry_mkclean(), which is called as part of the fsync
    operation 2).  This will cause the writes in step 3) above to generate
    page faults where we'll re-dirty the PMD radix tree entry, resulting in
    flushes in the fsync that happens in step 4).
    
    Fixes: 4b4bb46d ("dax: clear dirty entry tags on cache flush")
    Link: http://lkml.kernel.org/r/1482272586-21177-3-git-send-email-ross.zwisler@linux.intel.comSigned-off-by: default avatarRoss Zwisler <ross.zwisler@linux.intel.com>
    Reviewed-by: default avatarJan Kara <jack@suse.cz>
    Cc: Alexander Viro <viro@zeniv.linux.org.uk>
    Cc: Christoph Hellwig <hch@lst.de>
    Cc: Dan Williams <dan.j.williams@intel.com>
    Cc: Dave Chinner <david@fromorbit.com>
    Cc: Jan Kara <jack@suse.cz>
    Cc: Matthew Wilcox <mawilcox@microsoft.com>
    Cc: Dave Hansen <dave.hansen@intel.com>
    Signed-off-by: default avatarAndrew Morton <akpm@linux-foundation.org>
    Signed-off-by: default avatarLinus Torvalds <torvalds@linux-foundation.org>
    f729c8c9
memory.c 112 KB