mm: fix data corruption due to stale mmap reads
[sfrench/cifs-2.6.git] / fs / dax.c
index 6433650be833876eea42cd36ca109e4298bff073..123d9903c77d859c1ecfa79022ef66c68ce294c2 100644 (file)
--- a/fs/dax.c
+++ b/fs/dax.c
@@ -55,32 +55,6 @@ static int __init init_dax_wait_table(void)
 }
 fs_initcall(init_dax_wait_table);
 
-static long dax_map_atomic(struct block_device *bdev, struct blk_dax_ctl *dax)
-{
-       struct request_queue *q = bdev->bd_queue;
-       long rc = -EIO;
-
-       dax->addr = ERR_PTR(-EIO);
-       if (blk_queue_enter(q, true) != 0)
-               return rc;
-
-       rc = bdev_direct_access(bdev, dax);
-       if (rc < 0) {
-               dax->addr = ERR_PTR(rc);
-               blk_queue_exit(q);
-               return rc;
-       }
-       return rc;
-}
-
-static void dax_unmap_atomic(struct block_device *bdev,
-               const struct blk_dax_ctl *dax)
-{
-       if (IS_ERR(dax->addr))
-               return;
-       blk_queue_exit(bdev->bd_queue);
-}
-
 static int dax_is_pmd_entry(void *entry)
 {
        return (unsigned long)entry & RADIX_DAX_PMD;
@@ -101,26 +75,6 @@ static int dax_is_empty_entry(void *entry)
        return (unsigned long)entry & RADIX_DAX_EMPTY;
 }
 
-struct page *read_dax_sector(struct block_device *bdev, sector_t n)
-{
-       struct page *page = alloc_pages(GFP_KERNEL, 0);
-       struct blk_dax_ctl dax = {
-               .size = PAGE_SIZE,
-               .sector = n & ~((((int) PAGE_SIZE) / 512) - 1),
-       };
-       long rc;
-
-       if (!page)
-               return ERR_PTR(-ENOMEM);
-
-       rc = dax_map_atomic(bdev, &dax);
-       if (rc < 0)
-               return ERR_PTR(rc);
-       memcpy_from_pmem(page_address(page), dax.addr, PAGE_SIZE);
-       dax_unmap_atomic(bdev, &dax);
-       return page;
-}
-
 /*
  * DAX radix tree locking
  */
@@ -506,35 +460,6 @@ int dax_delete_mapping_entry(struct address_space *mapping, pgoff_t index)
        return ret;
 }
 
-/*
- * Invalidate exceptional DAX entry if easily possible. This handles DAX
- * entries for invalidate_inode_pages() so we evict the entry only if we can
- * do so without blocking.
- */
-int dax_invalidate_mapping_entry(struct address_space *mapping, pgoff_t index)
-{
-       int ret = 0;
-       void *entry, **slot;
-       struct radix_tree_root *page_tree = &mapping->page_tree;
-
-       spin_lock_irq(&mapping->tree_lock);
-       entry = __radix_tree_lookup(page_tree, index, NULL, &slot);
-       if (!entry || !radix_tree_exceptional_entry(entry) ||
-           slot_locked(mapping, slot))
-               goto out;
-       if (radix_tree_tag_get(page_tree, index, PAGECACHE_TAG_DIRTY) ||
-           radix_tree_tag_get(page_tree, index, PAGECACHE_TAG_TOWRITE))
-               goto out;
-       radix_tree_delete(page_tree, index);
-       mapping->nrexceptional--;
-       ret = 1;
-out:
-       spin_unlock_irq(&mapping->tree_lock);
-       if (ret)
-               dax_wake_mapping_entry_waiter(mapping, index, entry, true);
-       return ret;
-}
-
 /*
  * Invalidate exceptional DAX entry if it is clean.
  */
@@ -555,21 +480,25 @@ int dax_invalidate_mapping_entry_sync(struct address_space *mapping,
 static int dax_load_hole(struct address_space *mapping, void **entry,
                         struct vm_fault *vmf)
 {
+       struct inode *inode = mapping->host;
        struct page *page;
        int ret;
 
        /* Hole page already exists? Return it...  */
        if (!radix_tree_exceptional_entry(*entry)) {
                page = *entry;
-               goto out;
+               goto finish_fault;
        }
 
        /* This will replace locked radix tree entry with a hole page */
        page = find_or_create_page(mapping, vmf->pgoff,
                                   vmf->gfp_mask | __GFP_ZERO);
-       if (!page)
-               return VM_FAULT_OOM;
- out:
+       if (!page) {
+               ret = VM_FAULT_OOM;
+               goto out;
+       }
+
+finish_fault:
        vmf->page = page;
        ret = finish_fault(vmf);
        vmf->page = NULL;
@@ -577,26 +506,37 @@ static int dax_load_hole(struct address_space *mapping, void **entry,
        if (!ret) {
                /* Grab reference for PTE that is now referencing the page */
                get_page(page);
-               return VM_FAULT_NOPAGE;
+               ret = VM_FAULT_NOPAGE;
        }
+out:
+       trace_dax_load_hole(inode, vmf, ret);
        return ret;
 }
 
-static int copy_user_dax(struct block_device *bdev, sector_t sector, size_t size,
-               struct page *to, unsigned long vaddr)
+static int copy_user_dax(struct block_device *bdev, struct dax_device *dax_dev,
+               sector_t sector, size_t size, struct page *to,
+               unsigned long vaddr)
 {
-       struct blk_dax_ctl dax = {
-               .sector = sector,
-               .size = size,
-       };
-       void *vto;
-
-       if (dax_map_atomic(bdev, &dax) < 0)
-               return PTR_ERR(dax.addr);
+       void *vto, *kaddr;
+       pgoff_t pgoff;
+       pfn_t pfn;
+       long rc;
+       int id;
+
+       rc = bdev_dax_pgoff(bdev, sector, size, &pgoff);
+       if (rc)
+               return rc;
+
+       id = dax_read_lock();
+       rc = dax_direct_access(dax_dev, pgoff, PHYS_PFN(size), &kaddr, &pfn);
+       if (rc < 0) {
+               dax_read_unlock(id);
+               return rc;
+       }
        vto = kmap_atomic(to);
-       copy_user_page(vto, (void __force *)dax.addr, vaddr, to);
+       copy_user_page(vto, (void __force *)kaddr, vaddr, to);
        kunmap_atomic(vto);
-       dax_unmap_atomic(bdev, &dax);
+       dax_read_unlock(id);
        return 0;
 }
 
@@ -764,12 +704,16 @@ unlock_pte:
 }
 
 static int dax_writeback_one(struct block_device *bdev,
-               struct address_space *mapping, pgoff_t index, void *entry)
+               struct dax_device *dax_dev, struct address_space *mapping,
+               pgoff_t index, void *entry)
 {
        struct radix_tree_root *page_tree = &mapping->page_tree;
-       struct blk_dax_ctl dax;
-       void *entry2, **slot;
-       int ret = 0;
+       void *entry2, **slot, *kaddr;
+       long ret = 0, id;
+       sector_t sector;
+       pgoff_t pgoff;
+       size_t size;
+       pfn_t pfn;
 
        /*
         * A page got tagged dirty in DAX mapping? Something is seriously
@@ -818,26 +762,29 @@ static int dax_writeback_one(struct block_device *bdev,
         * 'entry'.  This allows us to flush for PMD_SIZE and not have to
         * worry about partial PMD writebacks.
         */
-       dax.sector = dax_radix_sector(entry);
-       dax.size = PAGE_SIZE << dax_radix_order(entry);
+       sector = dax_radix_sector(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;
 
        /*
-        * We cannot hold tree_lock while calling dax_map_atomic() because it
-        * eventually calls cond_resched().
+        * dax_direct_access() may sleep, so cannot hold tree_lock over
+        * its invocation.
         */
-       ret = dax_map_atomic(bdev, &dax);
-       if (ret < 0) {
-               put_locked_mapping_entry(mapping, index, entry);
-               return ret;
-       }
+       ret = dax_direct_access(dax_dev, pgoff, size / PAGE_SIZE, &kaddr, &pfn);
+       if (ret < 0)
+               goto dax_unlock;
 
-       if (WARN_ON_ONCE(ret < dax.size)) {
+       if (WARN_ON_ONCE(ret < size / PAGE_SIZE)) {
                ret = -EIO;
-               goto unmap;
+               goto dax_unlock;
        }
 
-       dax_mapping_entry_mkclean(mapping, index, pfn_t_to_pfn(dax.pfn));
-       wb_cache_pmem(dax.addr, dax.size);
+       dax_mapping_entry_mkclean(mapping, index, pfn_t_to_pfn(pfn));
+       wb_cache_pmem(kaddr, 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
@@ -847,8 +794,9 @@ static int dax_writeback_one(struct block_device *bdev,
        spin_lock_irq(&mapping->tree_lock);
        radix_tree_tag_clear(page_tree, index, PAGECACHE_TAG_DIRTY);
        spin_unlock_irq(&mapping->tree_lock);
- unmap:
-       dax_unmap_atomic(bdev, &dax);
+       trace_dax_writeback_one(mapping->host, index, size >> PAGE_SHIFT);
+ dax_unlock:
+       dax_read_unlock(id);
        put_locked_mapping_entry(mapping, index, entry);
        return ret;
 
@@ -869,6 +817,7 @@ int dax_writeback_mapping_range(struct address_space *mapping,
        struct inode *inode = mapping->host;
        pgoff_t start_index, end_index;
        pgoff_t indices[PAGEVEC_SIZE];
+       struct dax_device *dax_dev;
        struct pagevec pvec;
        bool done = false;
        int i, ret = 0;
@@ -879,9 +828,15 @@ int dax_writeback_mapping_range(struct address_space *mapping,
        if (!mapping->nrexceptional || wbc->sync_mode != WB_SYNC_ALL)
                return 0;
 
+       dax_dev = dax_get_by_host(bdev->bd_disk->disk_name);
+       if (!dax_dev)
+               return -EIO;
+
        start_index = wbc->range_start >> PAGE_SHIFT;
        end_index = wbc->range_end >> PAGE_SHIFT;
 
+       trace_dax_writeback_range(inode, start_index, end_index);
+
        tag_pages_for_writeback(mapping, start_index, end_index);
 
        pagevec_init(&pvec, 0);
@@ -899,38 +854,50 @@ int dax_writeback_mapping_range(struct address_space *mapping,
                                break;
                        }
 
-                       ret = dax_writeback_one(bdev, mapping, indices[i],
-                                       pvec.pages[i]);
+                       ret = dax_writeback_one(bdev, dax_dev, mapping,
+                                       indices[i], pvec.pages[i]);
                        if (ret < 0)
-                               return ret;
+                               goto out;
                }
        }
-       return 0;
+out:
+       put_dax(dax_dev);
+       trace_dax_writeback_range_done(inode, start_index, end_index);
+       return (ret < 0 ? ret : 0);
 }
 EXPORT_SYMBOL_GPL(dax_writeback_mapping_range);
 
 static int dax_insert_mapping(struct address_space *mapping,
-               struct block_device *bdev, sector_t sector, size_t size,
-               void **entryp, struct vm_area_struct *vma, struct vm_fault *vmf)
+               struct block_device *bdev, struct dax_device *dax_dev,
+               sector_t sector, size_t size, void **entryp,
+               struct vm_area_struct *vma, struct vm_fault *vmf)
 {
        unsigned long vaddr = vmf->address;
-       struct blk_dax_ctl dax = {
-               .sector = sector,
-               .size = size,
-       };
-       void *ret;
        void *entry = *entryp;
+       void *ret, *kaddr;
+       pgoff_t pgoff;
+       int id, rc;
+       pfn_t pfn;
 
-       if (dax_map_atomic(bdev, &dax) < 0)
-               return PTR_ERR(dax.addr);
-       dax_unmap_atomic(bdev, &dax);
+       rc = bdev_dax_pgoff(bdev, sector, size, &pgoff);
+       if (rc)
+               return rc;
+
+       id = dax_read_lock();
+       rc = dax_direct_access(dax_dev, pgoff, PHYS_PFN(size), &kaddr, &pfn);
+       if (rc < 0) {
+               dax_read_unlock(id);
+               return rc;
+       }
+       dax_read_unlock(id);
 
-       ret = dax_insert_mapping_entry(mapping, vmf, entry, dax.sector, 0);
+       ret = dax_insert_mapping_entry(mapping, vmf, entry, sector, 0);
        if (IS_ERR(ret))
                return PTR_ERR(ret);
        *entryp = ret;
 
-       return vm_insert_mixed(vma, vaddr, dax.pfn);
+       trace_dax_insert_mapping(mapping->host, vmf, ret);
+       return vm_insert_mixed(vma, vaddr, pfn);
 }
 
 /**
@@ -941,6 +908,7 @@ int dax_pfn_mkwrite(struct vm_fault *vmf)
 {
        struct file *file = vmf->vma->vm_file;
        struct address_space *mapping = file->f_mapping;
+       struct inode *inode = mapping->host;
        void *entry, **slot;
        pgoff_t index = vmf->pgoff;
 
@@ -950,6 +918,7 @@ int dax_pfn_mkwrite(struct vm_fault *vmf)
                if (entry)
                        put_unlocked_mapping_entry(mapping, index, entry);
                spin_unlock_irq(&mapping->tree_lock);
+               trace_dax_pfn_mkwrite_no_entry(inode, vmf, VM_FAULT_NOPAGE);
                return VM_FAULT_NOPAGE;
        }
        radix_tree_tag_set(&mapping->page_tree, index, PAGECACHE_TAG_DIRTY);
@@ -962,6 +931,7 @@ int dax_pfn_mkwrite(struct vm_fault *vmf)
         */
        finish_mkwrite_fault(vmf);
        put_locked_mapping_entry(mapping, index, entry);
+       trace_dax_pfn_mkwrite(inode, vmf, VM_FAULT_NOPAGE);
        return VM_FAULT_NOPAGE;
 }
 EXPORT_SYMBOL_GPL(dax_pfn_mkwrite);
@@ -979,24 +949,34 @@ static bool dax_range_is_aligned(struct block_device *bdev,
        return true;
 }
 
-int __dax_zero_page_range(struct block_device *bdev, sector_t sector,
-               unsigned int offset, unsigned int length)
+int __dax_zero_page_range(struct block_device *bdev,
+               struct dax_device *dax_dev, sector_t sector,
+               unsigned int offset, unsigned int size)
 {
-       struct blk_dax_ctl dax = {
-               .sector         = sector,
-               .size           = PAGE_SIZE,
-       };
-
-       if (dax_range_is_aligned(bdev, offset, length)) {
-               sector_t start_sector = dax.sector + (offset >> 9);
+       if (dax_range_is_aligned(bdev, offset, size)) {
+               sector_t start_sector = sector + (offset >> 9);
 
                return blkdev_issue_zeroout(bdev, start_sector,
-                               length >> 9, GFP_NOFS, 0);
+                               size >> 9, GFP_NOFS, 0);
        } else {
-               if (dax_map_atomic(bdev, &dax) < 0)
-                       return PTR_ERR(dax.addr);
-               clear_pmem(dax.addr + offset, length);
-               dax_unmap_atomic(bdev, &dax);
+               pgoff_t pgoff;
+               long rc, id;
+               void *kaddr;
+               pfn_t pfn;
+
+               rc = bdev_dax_pgoff(bdev, sector, size, &pgoff);
+               if (rc)
+                       return rc;
+
+               id = dax_read_lock();
+               rc = dax_direct_access(dax_dev, pgoff, PHYS_PFN(size), &kaddr,
+                               &pfn);
+               if (rc < 0) {
+                       dax_read_unlock(id);
+                       return rc;
+               }
+               clear_pmem(kaddr + offset, size);
+               dax_read_unlock(id);
        }
        return 0;
 }
@@ -1011,9 +991,12 @@ static loff_t
 dax_iomap_actor(struct inode *inode, loff_t pos, loff_t length, void *data,
                struct iomap *iomap)
 {
+       struct block_device *bdev = iomap->bdev;
+       struct dax_device *dax_dev = iomap->dax_dev;
        struct iov_iter *iter = data;
        loff_t end = pos + length, done = 0;
        ssize_t ret = 0;
+       int id;
 
        if (iov_iter_rw(iter) == READ) {
                end = min(end, i_size_read(inode));
@@ -1032,40 +1015,48 @@ dax_iomap_actor(struct inode *inode, loff_t pos, loff_t length, void *data,
         * into page tables. We have to tear down these mappings so that data
         * written by write(2) is visible in mmap.
         */
-       if ((iomap->flags & IOMAP_F_NEW) && inode->i_mapping->nrpages) {
+       if (iomap->flags & IOMAP_F_NEW) {
                invalidate_inode_pages2_range(inode->i_mapping,
                                              pos >> PAGE_SHIFT,
                                              (end - 1) >> PAGE_SHIFT);
        }
 
+       id = dax_read_lock();
        while (pos < end) {
                unsigned offset = pos & (PAGE_SIZE - 1);
-               struct blk_dax_ctl dax = { 0 };
+               const size_t size = ALIGN(length + offset, PAGE_SIZE);
+               const sector_t sector = dax_iomap_sector(iomap, pos);
                ssize_t map_len;
+               pgoff_t pgoff;
+               void *kaddr;
+               pfn_t pfn;
 
                if (fatal_signal_pending(current)) {
                        ret = -EINTR;
                        break;
                }
 
-               dax.sector = dax_iomap_sector(iomap, pos);
-               dax.size = (length + offset + PAGE_SIZE - 1) & PAGE_MASK;
-               map_len = dax_map_atomic(iomap->bdev, &dax);
+               ret = bdev_dax_pgoff(bdev, sector, size, &pgoff);
+               if (ret)
+                       break;
+
+               map_len = dax_direct_access(dax_dev, pgoff, PHYS_PFN(size),
+                               &kaddr, &pfn);
                if (map_len < 0) {
                        ret = map_len;
                        break;
                }
 
-               dax.addr += offset;
+               map_len = PFN_PHYS(map_len);
+               kaddr += offset;
                map_len -= offset;
                if (map_len > end - pos)
                        map_len = end - pos;
 
                if (iov_iter_rw(iter) == WRITE)
-                       map_len = copy_from_iter_pmem(dax.addr, map_len, iter);
+                       map_len = copy_from_iter_pmem(kaddr, map_len, iter);
                else
-                       map_len = copy_to_iter(dax.addr, map_len, iter);
-               dax_unmap_atomic(iomap->bdev, &dax);
+                       map_len = copy_to_iter(kaddr, map_len, iter);
                if (map_len <= 0) {
                        ret = map_len ? map_len : -EFAULT;
                        break;
@@ -1075,6 +1066,7 @@ dax_iomap_actor(struct inode *inode, loff_t pos, loff_t length, void *data,
                length -= map_len;
                done += map_len;
        }
+       dax_read_unlock(id);
 
        return done ? done : ret;
 }
@@ -1142,13 +1134,16 @@ static int dax_iomap_pte_fault(struct vm_fault *vmf,
        int vmf_ret = 0;
        void *entry;
 
+       trace_dax_pte_fault(inode, vmf, vmf_ret);
        /*
         * Check whether offset isn't beyond end of file now. Caller is supposed
         * to hold locks serializing us with truncate / punch hole so this is
         * a reliable test.
         */
-       if (pos >= i_size_read(inode))
-               return VM_FAULT_SIGBUS;
+       if (pos >= i_size_read(inode)) {
+               vmf_ret = VM_FAULT_SIGBUS;
+               goto out;
+       }
 
        if ((vmf->flags & FAULT_FLAG_WRITE) && !vmf->cow_page)
                flags |= IOMAP_WRITE;
@@ -1159,8 +1154,10 @@ static int dax_iomap_pte_fault(struct vm_fault *vmf,
         * that we never have to deal with more than a single extent here.
         */
        error = ops->iomap_begin(inode, pos, PAGE_SIZE, flags, &iomap);
-       if (error)
-               return dax_fault_return(error);
+       if (error) {
+               vmf_ret = dax_fault_return(error);
+               goto out;
+       }
        if (WARN_ON_ONCE(iomap.offset + iomap.length < pos + PAGE_SIZE)) {
                vmf_ret = dax_fault_return(-EIO);       /* fs corruption? */
                goto finish_iomap;
@@ -1181,8 +1178,8 @@ static int dax_iomap_pte_fault(struct vm_fault *vmf,
                        clear_user_highpage(vmf->cow_page, vaddr);
                        break;
                case IOMAP_MAPPED:
-                       error = copy_user_dax(iomap.bdev, sector, PAGE_SIZE,
-                                       vmf->cow_page, vaddr);
+                       error = copy_user_dax(iomap.bdev, iomap.dax_dev,
+                                       sector, PAGE_SIZE, vmf->cow_page, vaddr);
                        break;
                default:
                        WARN_ON_ONCE(1);
@@ -1207,8 +1204,8 @@ static int dax_iomap_pte_fault(struct vm_fault *vmf,
                        mem_cgroup_count_vm_event(vmf->vma->vm_mm, PGMAJFAULT);
                        major = VM_FAULT_MAJOR;
                }
-               error = dax_insert_mapping(mapping, iomap.bdev, sector,
-                               PAGE_SIZE, &entry, vmf->vma, vmf);
+               error = dax_insert_mapping(mapping, iomap.bdev, iomap.dax_dev,
+                               sector, PAGE_SIZE, &entry, vmf->vma, vmf);
                /* -EBUSY is fine, somebody else faulted on the same PTE */
                if (error == -EBUSY)
                        error = 0;
@@ -1244,6 +1241,8 @@ static int dax_iomap_pte_fault(struct vm_fault *vmf,
                 */
                ops->iomap_end(inode, pos, PAGE_SIZE, copied, flags, &iomap);
        }
+out:
+       trace_dax_pte_fault_done(inode, vmf, vmf_ret);
        return vmf_ret;
 }
 
@@ -1258,41 +1257,48 @@ static int dax_pmd_insert_mapping(struct vm_fault *vmf, struct iomap *iomap,
                loff_t pos, void **entryp)
 {
        struct address_space *mapping = vmf->vma->vm_file->f_mapping;
+       const sector_t sector = dax_iomap_sector(iomap, pos);
+       struct dax_device *dax_dev = iomap->dax_dev;
        struct block_device *bdev = iomap->bdev;
        struct inode *inode = mapping->host;
-       struct blk_dax_ctl dax = {
-               .sector = dax_iomap_sector(iomap, pos),
-               .size = PMD_SIZE,
-       };
-       long length = dax_map_atomic(bdev, &dax);
-       void *ret = NULL;
-
-       if (length < 0) /* dax_map_atomic() failed */
+       const size_t size = PMD_SIZE;
+       void *ret = NULL, *kaddr;
+       long length = 0;
+       pgoff_t pgoff;
+       pfn_t pfn;
+       int id;
+
+       if (bdev_dax_pgoff(bdev, sector, size, &pgoff) != 0)
                goto fallback;
-       if (length < PMD_SIZE)
-               goto unmap_fallback;
-       if (pfn_t_to_pfn(dax.pfn) & PG_PMD_COLOUR)
-               goto unmap_fallback;
-       if (!pfn_t_devmap(dax.pfn))
-               goto unmap_fallback;
-
-       dax_unmap_atomic(bdev, &dax);
 
-       ret = dax_insert_mapping_entry(mapping, vmf, *entryp, dax.sector,
+       id = dax_read_lock();
+       length = dax_direct_access(dax_dev, pgoff, PHYS_PFN(size), &kaddr, &pfn);
+       if (length < 0)
+               goto unlock_fallback;
+       length = PFN_PHYS(length);
+
+       if (length < size)
+               goto unlock_fallback;
+       if (pfn_t_to_pfn(pfn) & PG_PMD_COLOUR)
+               goto unlock_fallback;
+       if (!pfn_t_devmap(pfn))
+               goto unlock_fallback;
+       dax_read_unlock(id);
+
+       ret = dax_insert_mapping_entry(mapping, vmf, *entryp, sector,
                        RADIX_DAX_PMD);
        if (IS_ERR(ret))
                goto fallback;
        *entryp = ret;
 
-       trace_dax_pmd_insert_mapping(inode, vmf, length, dax.pfn, ret);
+       trace_dax_pmd_insert_mapping(inode, vmf, length, pfn, ret);
        return vmf_insert_pfn_pmd(vmf->vma, vmf->address, vmf->pmd,
-                       dax.pfn, vmf->flags & FAULT_FLAG_WRITE);
+                       pfn, vmf->flags & FAULT_FLAG_WRITE);
 
- unmap_fallback:
-       dax_unmap_atomic(bdev, &dax);
+unlock_fallback:
+       dax_read_unlock(id);
 fallback:
-       trace_dax_pmd_insert_mapping_fallback(inode, vmf, length,
-                       dax.pfn, ret);
+       trace_dax_pmd_insert_mapping_fallback(inode, vmf, length, pfn, ret);
        return VM_FAULT_FALLBACK;
 }