Merge tag 'dax-fixes-5.3-rc4' of git://git.kernel.org/pub/scm/linux/kernel/git/nvdimm...
authorLinus Torvalds <torvalds@linux-foundation.org>
Sun, 11 Aug 2019 20:15:10 +0000 (13:15 -0700)
committerLinus Torvalds <torvalds@linux-foundation.org>
Sun, 11 Aug 2019 20:15:10 +0000 (13:15 -0700)
Pull dax fixes from Dan Williams:
 "A filesystem-dax and device-dax fix for v5.3.

  The filesystem-dax fix is tagged for stable as the implementation has
  been mistakenly throwing away all cow pages on any truncate or hole
  punch operation as part of the solution to coordinate device-dma vs
  truncate to dax pages.

  The device-dax change fixes up a regression this cycle from the
  introduction of a common 'internal per-cpu-ref' implementation.

  Summary:

   - Fix dax_layout_busy_page() to not discard private cow pages of
     fs/dax private mappings.

   - Update the memremap_pages core to properly cleanup on behalf of
     internal reference-count users like device-dax"

* tag 'dax-fixes-5.3-rc4' of git://git.kernel.org/pub/scm/linux/kernel/git/nvdimm/nvdimm:
  mm/memremap: Fix reuse of pgmap instances with internal references
  dax: dax_layout_busy_page() should not unmap cow pages

fs/dax.c
mm/memremap.c

index b64964ef44f62b8ad3a261396d16809d2667e274..6bf81f931de39e48bc2983a1c901b1a6643443f8 100644 (file)
--- a/fs/dax.c
+++ b/fs/dax.c
@@ -600,7 +600,7 @@ struct page *dax_layout_busy_page(struct address_space *mapping)
         * guaranteed to either see new references or prevent new
         * references from being established.
         */
-       unmap_mapping_range(mapping, 0, 0, 1);
+       unmap_mapping_range(mapping, 0, 0, 0);
 
        xas_lock_irq(&xas);
        xas_for_each(&xas, entry, ULONG_MAX) {
index 6ee03a816d67a889729e834b8c614675ac4cf94c..86432650f829877cf7aa031e540909071ba56ec9 100644 (file)
@@ -91,6 +91,12 @@ static void dev_pagemap_cleanup(struct dev_pagemap *pgmap)
                wait_for_completion(&pgmap->done);
                percpu_ref_exit(pgmap->ref);
        }
+       /*
+        * Undo the pgmap ref assignment for the internal case as the
+        * caller may re-enable the same pgmap.
+        */
+       if (pgmap->ref == &pgmap->internal_ref)
+               pgmap->ref = NULL;
 }
 
 static void devm_memremap_pages_release(void *data)