]> git.proxmox.com Git - mirror_ubuntu-jammy-kernel.git/blobdiff - fs/dax.c
page cache: use xa_lock
[mirror_ubuntu-jammy-kernel.git] / fs / dax.c
index 0276df90e86c588f1908409fee23c0152e0d63a6..aaec72ded1b63c9a2944a228d201be239f77ada1 100644 (file)
--- a/fs/dax.c
+++ b/fs/dax.c
@@ -73,16 +73,15 @@ fs_initcall(init_dax_wait_table);
 #define RADIX_DAX_ZERO_PAGE    (1 << (RADIX_TREE_EXCEPTIONAL_SHIFT + 2))
 #define RADIX_DAX_EMPTY                (1 << (RADIX_TREE_EXCEPTIONAL_SHIFT + 3))
 
-static unsigned long dax_radix_sector(void *entry)
+static unsigned long dax_radix_pfn(void *entry)
 {
        return (unsigned long)entry >> RADIX_DAX_SHIFT;
 }
 
-static void *dax_radix_locked_entry(sector_t sector, unsigned long flags)
+static void *dax_radix_locked_entry(unsigned long pfn, unsigned long flags)
 {
        return (void *)(RADIX_TREE_EXCEPTIONAL_ENTRY | flags |
-                       ((unsigned long)sector << RADIX_DAX_SHIFT) |
-                       RADIX_DAX_ENTRY_LOCK);
+                       (pfn << RADIX_DAX_SHIFT) | RADIX_DAX_ENTRY_LOCK);
 }
 
 static unsigned int dax_radix_order(void *entry)
@@ -159,11 +158,9 @@ static int wake_exceptional_entry_func(wait_queue_entry_t *wait, unsigned int mo
 }
 
 /*
- * We do not necessarily hold the mapping->tree_lock when we call this
- * function so it is possible that 'entry' is no longer a valid item in the
- * radix tree.  This is okay because all we really need to do is to find the
- * correct waitqueue where tasks might be waiting for that old 'entry' and
- * wake them.
+ * @entry may no longer be the entry at the index in the mapping.
+ * The important information it's conveying is whether the entry at
+ * this index used to be a PMD entry.
  */
 static void dax_wake_mapping_entry_waiter(struct address_space *mapping,
                pgoff_t index, void *entry, bool wake_all)
@@ -175,7 +172,7 @@ static void dax_wake_mapping_entry_waiter(struct address_space *mapping,
 
        /*
         * Checking for locked entry and prepare_to_wait_exclusive() happens
-        * under mapping->tree_lock, ditto for entry handling in our callers.
+        * under the i_pages lock, ditto for entry handling in our callers.
         * So at this point all tasks that could have seen our entry locked
         * must be in the waitqueue and the following check will see them.
         */
@@ -184,41 +181,39 @@ static void dax_wake_mapping_entry_waiter(struct address_space *mapping,
 }
 
 /*
- * Check whether the given slot is locked. The function must be called with
- * mapping->tree_lock held
+ * Check whether the given slot is locked.  Must be called with the i_pages
+ * lock held.
  */
 static inline int slot_locked(struct address_space *mapping, void **slot)
 {
        unsigned long entry = (unsigned long)
-               radix_tree_deref_slot_protected(slot, &mapping->tree_lock);
+               radix_tree_deref_slot_protected(slot, &mapping->i_pages.xa_lock);
        return entry & RADIX_DAX_ENTRY_LOCK;
 }
 
 /*
- * Mark the given slot is locked. The function must be called with
- * mapping->tree_lock held
+ * Mark the given slot as locked.  Must be called with the i_pages lock held.
  */
 static inline void *lock_slot(struct address_space *mapping, void **slot)
 {
        unsigned long entry = (unsigned long)
-               radix_tree_deref_slot_protected(slot, &mapping->tree_lock);
+               radix_tree_deref_slot_protected(slot, &mapping->i_pages.xa_lock);
 
        entry |= RADIX_DAX_ENTRY_LOCK;
-       radix_tree_replace_slot(&mapping->page_tree, slot, (void *)entry);
+       radix_tree_replace_slot(&mapping->i_pages, slot, (void *)entry);
        return (void *)entry;
 }
 
 /*
- * Mark the given slot is unlocked. The function must be called with
- * mapping->tree_lock held
+ * Mark the given slot as unlocked.  Must be called with the i_pages lock held.
  */
 static inline void *unlock_slot(struct address_space *mapping, void **slot)
 {
        unsigned long entry = (unsigned long)
-               radix_tree_deref_slot_protected(slot, &mapping->tree_lock);
+               radix_tree_deref_slot_protected(slot, &mapping->i_pages.xa_lock);
 
        entry &= ~(unsigned long)RADIX_DAX_ENTRY_LOCK;
-       radix_tree_replace_slot(&mapping->page_tree, slot, (void *)entry);
+       radix_tree_replace_slot(&mapping->i_pages, slot, (void *)entry);
        return (void *)entry;
 }
 
@@ -229,7 +224,7 @@ static inline void *unlock_slot(struct address_space *mapping, void **slot)
  * put_locked_mapping_entry() when he locked the entry and now wants to
  * unlock it.
  *
- * The function must be called with mapping->tree_lock held.
+ * Must be called with the i_pages lock held.
  */
 static void *get_unlocked_mapping_entry(struct address_space *mapping,
                                        pgoff_t index, void ***slotp)
@@ -242,7 +237,7 @@ static void *get_unlocked_mapping_entry(struct address_space *mapping,
        ewait.wait.func = wake_exceptional_entry_func;
 
        for (;;) {
-               entry = __radix_tree_lookup(&mapping->page_tree, index, NULL,
+               entry = __radix_tree_lookup(&mapping->i_pages, index, NULL,
                                          &slot);
                if (!entry ||
                    WARN_ON_ONCE(!radix_tree_exceptional_entry(entry)) ||
@@ -255,10 +250,10 @@ static void *get_unlocked_mapping_entry(struct address_space *mapping,
                wq = dax_entry_waitqueue(mapping, index, entry, &ewait.key);
                prepare_to_wait_exclusive(wq, &ewait.wait,
                                          TASK_UNINTERRUPTIBLE);
-               spin_unlock_irq(&mapping->tree_lock);
+               xa_unlock_irq(&mapping->i_pages);
                schedule();
                finish_wait(wq, &ewait.wait);
-               spin_lock_irq(&mapping->tree_lock);
+               xa_lock_irq(&mapping->i_pages);
        }
 }
 
@@ -267,15 +262,15 @@ static void dax_unlock_mapping_entry(struct address_space *mapping,
 {
        void *entry, **slot;
 
-       spin_lock_irq(&mapping->tree_lock);
-       entry = __radix_tree_lookup(&mapping->page_tree, index, NULL, &slot);
+       xa_lock_irq(&mapping->i_pages);
+       entry = __radix_tree_lookup(&mapping->i_pages, index, NULL, &slot);
        if (WARN_ON_ONCE(!entry || !radix_tree_exceptional_entry(entry) ||
                         !slot_locked(mapping, slot))) {
-               spin_unlock_irq(&mapping->tree_lock);
+               xa_unlock_irq(&mapping->i_pages);
                return;
        }
        unlock_slot(mapping, slot);
-       spin_unlock_irq(&mapping->tree_lock);
+       xa_unlock_irq(&mapping->i_pages);
        dax_wake_mapping_entry_waiter(mapping, index, entry, false);
 }
 
@@ -299,6 +294,63 @@ static void put_unlocked_mapping_entry(struct address_space *mapping,
        dax_wake_mapping_entry_waiter(mapping, index, entry, false);
 }
 
+static unsigned long dax_entry_size(void *entry)
+{
+       if (dax_is_zero_entry(entry))
+               return 0;
+       else if (dax_is_empty_entry(entry))
+               return 0;
+       else if (dax_is_pmd_entry(entry))
+               return PMD_SIZE;
+       else
+               return PAGE_SIZE;
+}
+
+static unsigned long dax_radix_end_pfn(void *entry)
+{
+       return dax_radix_pfn(entry) + dax_entry_size(entry) / PAGE_SIZE;
+}
+
+/*
+ * Iterate through all mapped pfns represented by an entry, i.e. skip
+ * 'empty' and 'zero' entries.
+ */
+#define for_each_mapped_pfn(entry, pfn) \
+       for (pfn = dax_radix_pfn(entry); \
+                       pfn < dax_radix_end_pfn(entry); pfn++)
+
+static void dax_associate_entry(void *entry, struct address_space *mapping)
+{
+       unsigned long pfn;
+
+       if (IS_ENABLED(CONFIG_FS_DAX_LIMITED))
+               return;
+
+       for_each_mapped_pfn(entry, pfn) {
+               struct page *page = pfn_to_page(pfn);
+
+               WARN_ON_ONCE(page->mapping);
+               page->mapping = mapping;
+       }
+}
+
+static void dax_disassociate_entry(void *entry, struct address_space *mapping,
+               bool trunc)
+{
+       unsigned long pfn;
+
+       if (IS_ENABLED(CONFIG_FS_DAX_LIMITED))
+               return;
+
+       for_each_mapped_pfn(entry, pfn) {
+               struct page *page = pfn_to_page(pfn);
+
+               WARN_ON_ONCE(trunc && page_ref_count(page) > 1);
+               WARN_ON_ONCE(page->mapping && page->mapping != mapping);
+               page->mapping = NULL;
+       }
+}
+
 /*
  * Find radix tree entry at given index. If it points to an exceptional entry,
  * return it with the radix tree entry locked. If the radix tree doesn't
@@ -332,7 +384,7 @@ static void *grab_mapping_entry(struct address_space *mapping, pgoff_t index,
        void *entry, **slot;
 
 restart:
-       spin_lock_irq(&mapping->tree_lock);
+       xa_lock_irq(&mapping->i_pages);
        entry = get_unlocked_mapping_entry(mapping, index, &slot);
 
        if (WARN_ON_ONCE(entry && !radix_tree_exceptional_entry(entry))) {
@@ -364,12 +416,12 @@ restart:
                if (pmd_downgrade) {
                        /*
                         * Make sure 'entry' remains valid while we drop
-                        * mapping->tree_lock.
+                        * the i_pages lock.
                         */
                        entry = lock_slot(mapping, slot);
                }
 
-               spin_unlock_irq(&mapping->tree_lock);
+               xa_unlock_irq(&mapping->i_pages);
                /*
                 * Besides huge zero pages the only other thing that gets
                 * downgraded are empty entries which don't need to be
@@ -386,26 +438,27 @@ restart:
                                put_locked_mapping_entry(mapping, index);
                        return ERR_PTR(err);
                }
-               spin_lock_irq(&mapping->tree_lock);
+               xa_lock_irq(&mapping->i_pages);
 
                if (!entry) {
                        /*
-                        * We needed to drop the page_tree lock while calling
+                        * We needed to drop the i_pages lock while calling
                         * radix_tree_preload() and we didn't have an entry to
                         * lock.  See if another thread inserted an entry at
                         * our index during this time.
                         */
-                       entry = __radix_tree_lookup(&mapping->page_tree, index,
+                       entry = __radix_tree_lookup(&mapping->i_pages, index,
                                        NULL, &slot);
                        if (entry) {
                                radix_tree_preload_end();
-                               spin_unlock_irq(&mapping->tree_lock);
+                               xa_unlock_irq(&mapping->i_pages);
                                goto restart;
                        }
                }
 
                if (pmd_downgrade) {
-                       radix_tree_delete(&mapping->page_tree, index);
+                       dax_disassociate_entry(entry, mapping, false);
+                       radix_tree_delete(&mapping->i_pages, index);
                        mapping->nrexceptional--;
                        dax_wake_mapping_entry_waiter(mapping, index, entry,
                                        true);
@@ -413,11 +466,11 @@ restart:
 
                entry = dax_radix_locked_entry(0, size_flag | RADIX_DAX_EMPTY);
 
-               err = __radix_tree_insert(&mapping->page_tree, index,
+               err = __radix_tree_insert(&mapping->i_pages, index,
                                dax_radix_order(entry), entry);
                radix_tree_preload_end();
                if (err) {
-                       spin_unlock_irq(&mapping->tree_lock);
+                       xa_unlock_irq(&mapping->i_pages);
                        /*
                         * Our insertion of a DAX entry failed, most likely
                         * because we were inserting a PMD entry and it
@@ -430,12 +483,12 @@ restart:
                }
                /* Good, we have inserted empty locked entry into the tree. */
                mapping->nrexceptional++;
-               spin_unlock_irq(&mapping->tree_lock);
+               xa_unlock_irq(&mapping->i_pages);
                return entry;
        }
        entry = lock_slot(mapping, slot);
  out_unlock:
-       spin_unlock_irq(&mapping->tree_lock);
+       xa_unlock_irq(&mapping->i_pages);
        return entry;
 }
 
@@ -444,22 +497,23 @@ static int __dax_invalidate_mapping_entry(struct address_space *mapping,
 {
        int ret = 0;
        void *entry;
-       struct radix_tree_root *page_tree = &mapping->page_tree;
+       struct radix_tree_root *pages = &mapping->i_pages;
 
-       spin_lock_irq(&mapping->tree_lock);
+       xa_lock_irq(pages);
        entry = get_unlocked_mapping_entry(mapping, index, NULL);
        if (!entry || WARN_ON_ONCE(!radix_tree_exceptional_entry(entry)))
                goto out;
        if (!trunc &&
-           (radix_tree_tag_get(page_tree, index, PAGECACHE_TAG_DIRTY) ||
-            radix_tree_tag_get(page_tree, index, PAGECACHE_TAG_TOWRITE)))
+           (radix_tree_tag_get(pages, index, PAGECACHE_TAG_DIRTY) ||
+            radix_tree_tag_get(pages, index, PAGECACHE_TAG_TOWRITE)))
                goto out;
-       radix_tree_delete(page_tree, index);
+       dax_disassociate_entry(entry, mapping, trunc);
+       radix_tree_delete(pages, index);
        mapping->nrexceptional--;
        ret = 1;
 out:
        put_unlocked_mapping_entry(mapping, index, entry);
-       spin_unlock_irq(&mapping->tree_lock);
+       xa_unlock_irq(pages);
        return ret;
 }
 /*
@@ -526,12 +580,13 @@ static int copy_user_dax(struct block_device *bdev, struct dax_device *dax_dev,
  */
 static void *dax_insert_mapping_entry(struct address_space *mapping,
                                      struct vm_fault *vmf,
-                                     void *entry, sector_t sector,
+                                     void *entry, pfn_t pfn_t,
                                      unsigned long flags, bool dirty)
 {
-       struct radix_tree_root *page_tree = &mapping->page_tree;
-       void *new_entry;
+       struct radix_tree_root *pages = &mapping->i_pages;
+       unsigned long pfn = pfn_t_to_pfn(pfn_t);
        pgoff_t index = vmf->pgoff;
+       void *new_entry;
 
        if (dirty)
                __mark_inode_dirty(mapping->host, I_DIRTY_PAGES);
@@ -545,8 +600,12 @@ static void *dax_insert_mapping_entry(struct address_space *mapping,
                        unmap_mapping_pages(mapping, vmf->pgoff, 1, false);
        }
 
-       spin_lock_irq(&mapping->tree_lock);
-       new_entry = dax_radix_locked_entry(sector, flags);
+       xa_lock_irq(pages);
+       new_entry = dax_radix_locked_entry(pfn, flags);
+       if (dax_entry_size(entry) != dax_entry_size(new_entry)) {
+               dax_disassociate_entry(entry, mapping, false);
+               dax_associate_entry(new_entry, mapping);
+       }
 
        if (dax_is_zero_entry(entry) || dax_is_empty_entry(entry)) {
                /*
@@ -561,17 +620,17 @@ static void *dax_insert_mapping_entry(struct address_space *mapping,
                void **slot;
                void *ret;
 
-               ret = __radix_tree_lookup(page_tree, index, &node, &slot);
+               ret = __radix_tree_lookup(pages, index, &node, &slot);
                WARN_ON_ONCE(ret != entry);
-               __radix_tree_replace(page_tree, node, slot,
+               __radix_tree_replace(pages, node, slot,
                                     new_entry, NULL);
                entry = new_entry;
        }
 
        if (dirty)
-               radix_tree_tag_set(page_tree, index, PAGECACHE_TAG_DIRTY);
+               radix_tree_tag_set(pages, index, PAGECACHE_TAG_DIRTY);
 
-       spin_unlock_irq(&mapping->tree_lock);
+       xa_unlock_irq(pages);
        return entry;
 }
 
@@ -657,17 +716,14 @@ unlock_pte:
        i_mmap_unlock_read(mapping);
 }
 
-static int dax_writeback_one(struct block_device *bdev,
-               struct dax_device *dax_dev, struct address_space *mapping,
-               pgoff_t index, void *entry)
+static int dax_writeback_one(struct dax_device *dax_dev,
+               struct address_space *mapping, pgoff_t index, void *entry)
 {
-       struct radix_tree_root *page_tree = &mapping->page_tree;
-       void *entry2, **slot, *kaddr;
-       long ret = 0, id;
-       sector_t sector;
-       pgoff_t pgoff;
+       struct radix_tree_root *pages = &mapping->i_pages;
+       void *entry2, **slot;
+       unsigned long pfn;
+       long ret = 0;
        size_t size;
-       pfn_t pfn;
 
        /*
         * A page got tagged dirty in DAX mapping? Something is seriously
@@ -676,17 +732,17 @@ static int dax_writeback_one(struct block_device *bdev,
        if (WARN_ON(!radix_tree_exceptional_entry(entry)))
                return -EIO;
 
-       spin_lock_irq(&mapping->tree_lock);
+       xa_lock_irq(pages);
        entry2 = get_unlocked_mapping_entry(mapping, index, &slot);
        /* Entry got punched out / reallocated? */
        if (!entry2 || WARN_ON_ONCE(!radix_tree_exceptional_entry(entry2)))
                goto put_unlocked;
        /*
         * Entry got reallocated elsewhere? No need to writeback. We have to
-        * compare sectors as we must not bail out due to difference in lockbit
+        * compare pfns as we must not bail out due to difference in lockbit
         * or entry type.
         */
-       if (dax_radix_sector(entry2) != dax_radix_sector(entry))
+       if (dax_radix_pfn(entry2) != dax_radix_pfn(entry))
                goto put_unlocked;
        if (WARN_ON_ONCE(dax_is_empty_entry(entry) ||
                                dax_is_zero_entry(entry))) {
@@ -695,7 +751,7 @@ static int dax_writeback_one(struct block_device *bdev,
        }
 
        /* Another fsync thread may have already written back this entry */
-       if (!radix_tree_tag_get(page_tree, index, PAGECACHE_TAG_TOWRITE))
+       if (!radix_tree_tag_get(pages, index, PAGECACHE_TAG_TOWRITE))
                goto put_unlocked;
        /* Lock the entry to serialize with page faults */
        entry = lock_slot(mapping, slot);
@@ -703,60 +759,40 @@ static int dax_writeback_one(struct block_device *bdev,
         * We can clear the tag now but we have to be careful so that concurrent
         * dax_writeback_one() calls for the same index cannot finish before we
         * actually flush the caches. This is achieved as the calls will look
-        * at the entry only under tree_lock and once they do that they will
-        * see the entry locked and wait for it to unlock.
+        * at the entry only under the i_pages lock and once they do that
+        * they will see the entry locked and wait for it to unlock.
         */
-       radix_tree_tag_clear(page_tree, index, PAGECACHE_TAG_TOWRITE);
-       spin_unlock_irq(&mapping->tree_lock);
+       radix_tree_tag_clear(pages, index, PAGECACHE_TAG_TOWRITE);
+       xa_unlock_irq(pages);
 
        /*
         * Even if dax_writeback_mapping_range() was given a wbc->range_start
         * in the middle of a PMD, the 'index' we are given will be aligned to
-        * the start index of the PMD, as will the sector we pull from
-        * 'entry'.  This allows us to flush for PMD_SIZE and not have to
-        * worry about partial PMD writebacks.
+        * the start index of the PMD, as will the pfn we pull from 'entry'.
+        * This allows us to flush for PMD_SIZE and not have to worry about
+        * partial PMD writebacks.
         */
-       sector = dax_radix_sector(entry);
+       pfn = dax_radix_pfn(entry);
        size = PAGE_SIZE << dax_radix_order(entry);
 
-       id = dax_read_lock();
-       ret = bdev_dax_pgoff(bdev, sector, size, &pgoff);
-       if (ret)
-               goto dax_unlock;
-
-       /*
-        * dax_direct_access() may sleep, so cannot hold tree_lock over
-        * its invocation.
-        */
-       ret = dax_direct_access(dax_dev, pgoff, size / PAGE_SIZE, &kaddr, &pfn);
-       if (ret < 0)
-               goto dax_unlock;
-
-       if (WARN_ON_ONCE(ret < size / PAGE_SIZE)) {
-               ret = -EIO;
-               goto dax_unlock;
-       }
-
-       dax_mapping_entry_mkclean(mapping, index, pfn_t_to_pfn(pfn));
-       dax_flush(dax_dev, kaddr, size);
+       dax_mapping_entry_mkclean(mapping, index, pfn);
+       dax_flush(dax_dev, page_address(pfn_to_page(pfn)), size);
        /*
         * After we have flushed the cache, we can clear the dirty tag. There
         * cannot be new dirty data in the pfn after the flush has completed as
         * the pfn mappings are writeprotected and fault waits for mapping
         * entry lock.
         */
-       spin_lock_irq(&mapping->tree_lock);
-       radix_tree_tag_clear(page_tree, index, PAGECACHE_TAG_DIRTY);
-       spin_unlock_irq(&mapping->tree_lock);
+       xa_lock_irq(pages);
+       radix_tree_tag_clear(pages, index, PAGECACHE_TAG_DIRTY);
+       xa_unlock_irq(pages);
        trace_dax_writeback_one(mapping->host, index, size >> PAGE_SHIFT);
- dax_unlock:
-       dax_read_unlock(id);
        put_locked_mapping_entry(mapping, index);
        return ret;
 
  put_unlocked:
        put_unlocked_mapping_entry(mapping, index, entry2);
-       spin_unlock_irq(&mapping->tree_lock);
+       xa_unlock_irq(pages);
        return ret;
 }
 
@@ -808,8 +844,8 @@ int dax_writeback_mapping_range(struct address_space *mapping,
                                break;
                        }
 
-                       ret = dax_writeback_one(bdev, dax_dev, mapping,
-                                       indices[i], pvec.pages[i]);
+                       ret = dax_writeback_one(dax_dev, mapping, indices[i],
+                                       pvec.pages[i]);
                        if (ret < 0) {
                                mapping_set_error(mapping, ret);
                                goto out;
@@ -877,6 +913,7 @@ static int dax_load_hole(struct address_space *mapping, void *entry,
        int ret = VM_FAULT_NOPAGE;
        struct page *zero_page;
        void *entry2;
+       pfn_t pfn;
 
        zero_page = ZERO_PAGE(0);
        if (unlikely(!zero_page)) {
@@ -884,14 +921,15 @@ static int dax_load_hole(struct address_space *mapping, void *entry,
                goto out;
        }
 
-       entry2 = dax_insert_mapping_entry(mapping, vmf, entry, 0,
+       pfn = page_to_pfn_t(zero_page);
+       entry2 = dax_insert_mapping_entry(mapping, vmf, entry, pfn,
                        RADIX_DAX_ZERO_PAGE, false);
        if (IS_ERR(entry2)) {
                ret = VM_FAULT_SIGBUS;
                goto out;
        }
 
-       vm_insert_mixed(vmf->vma, vaddr, page_to_pfn_t(zero_page));
+       vm_insert_mixed(vmf->vma, vaddr, pfn);
 out:
        trace_dax_load_hole(inode, vmf, ret);
        return ret;
@@ -1200,8 +1238,7 @@ static int dax_iomap_pte_fault(struct vm_fault *vmf, pfn_t *pfnp,
                if (error < 0)
                        goto error_finish_iomap;
 
-               entry = dax_insert_mapping_entry(mapping, vmf, entry,
-                                                dax_iomap_sector(&iomap, pos),
+               entry = dax_insert_mapping_entry(mapping, vmf, entry, pfn,
                                                 0, write && !sync);
                if (IS_ERR(entry)) {
                        error = PTR_ERR(entry);
@@ -1280,13 +1317,15 @@ static int dax_pmd_load_hole(struct vm_fault *vmf, struct iomap *iomap,
        void *ret = NULL;
        spinlock_t *ptl;
        pmd_t pmd_entry;
+       pfn_t pfn;
 
        zero_page = mm_get_huge_zero_page(vmf->vma->vm_mm);
 
        if (unlikely(!zero_page))
                goto fallback;
 
-       ret = dax_insert_mapping_entry(mapping, vmf, entry, 0,
+       pfn = page_to_pfn_t(zero_page);
+       ret = dax_insert_mapping_entry(mapping, vmf, entry, pfn,
                        RADIX_DAX_PMD | RADIX_DAX_ZERO_PAGE, false);
        if (IS_ERR(ret))
                goto fallback;
@@ -1409,8 +1448,7 @@ static int dax_iomap_pmd_fault(struct vm_fault *vmf, pfn_t *pfnp,
                if (error < 0)
                        goto finish_iomap;
 
-               entry = dax_insert_mapping_entry(mapping, vmf, entry,
-                                               dax_iomap_sector(&iomap, pos),
+               entry = dax_insert_mapping_entry(mapping, vmf, entry, pfn,
                                                RADIX_DAX_PMD, write && !sync);
                if (IS_ERR(entry))
                        goto finish_iomap;
@@ -1524,21 +1562,21 @@ static int dax_insert_pfn_mkwrite(struct vm_fault *vmf,
        pgoff_t index = vmf->pgoff;
        int vmf_ret, error;
 
-       spin_lock_irq(&mapping->tree_lock);
+       xa_lock_irq(&mapping->i_pages);
        entry = get_unlocked_mapping_entry(mapping, index, &slot);
        /* Did we race with someone splitting entry or so? */
        if (!entry ||
            (pe_size == PE_SIZE_PTE && !dax_is_pte_entry(entry)) ||
            (pe_size == PE_SIZE_PMD && !dax_is_pmd_entry(entry))) {
                put_unlocked_mapping_entry(mapping, index, entry);
-               spin_unlock_irq(&mapping->tree_lock);
+               xa_unlock_irq(&mapping->i_pages);
                trace_dax_insert_pfn_mkwrite_no_entry(mapping->host, vmf,
                                                      VM_FAULT_NOPAGE);
                return VM_FAULT_NOPAGE;
        }
-       radix_tree_tag_set(&mapping->page_tree, index, PAGECACHE_TAG_DIRTY);
+       radix_tree_tag_set(&mapping->i_pages, index, PAGECACHE_TAG_DIRTY);
        entry = lock_slot(mapping, slot);
-       spin_unlock_irq(&mapping->tree_lock);
+       xa_unlock_irq(&mapping->i_pages);
        switch (pe_size) {
        case PE_SIZE_PTE:
                error = vm_insert_mixed_mkwrite(vmf->vma, vmf->address, pfn);