Re: [PATCH 13/13] ext4: Support for synchronous DAX faults
From: Christoph Hellwig <hch@infradead.org>
Date: 2017-08-23 18:37:15
Also in:
linux-fsdevel, linux-xfs, nvdimm
From: Christoph Hellwig <hch@infradead.org>
Date: 2017-08-23 18:37:15
Also in:
linux-fsdevel, linux-xfs, nvdimm
+ pfn_t pfn; if (write) { sb_start_pagefault(sb);@@ -287,16 +288,39 @@ static int ext4_dax_huge_fault(struct vm_fault *vmf, down_read(&EXT4_I(inode)->i_mmap_sem); handle = ext4_journal_start_sb(sb, EXT4_HT_WRITE_PAGE, EXT4_DATA_TRANS_BLOCKS(sb)); + if (IS_ERR(handle)) { + up_read(&EXT4_I(inode)->i_mmap_sem); + sb_end_pagefault(sb); + return VM_FAULT_SIGBUS; + } } else { down_read(&EXT4_I(inode)->i_mmap_sem); } - if (!IS_ERR(handle)) - result = dax_iomap_fault(vmf, pe_size, &ext4_iomap_ops, NULL); - else - result = VM_FAULT_SIGBUS; + result = dax_iomap_fault(vmf, pe_size, &ext4_iomap_ops, &pfn);
Maybe split the error handling refactor into a simple prep patch to make this one more readable?
+ /* Write fault but PFN mapped only RO? */
+ if (result & VM_FAULT_NEEDDSYNC) {
+ int err;
+ loff_t start = ((loff_t)vmf->pgoff) << PAGE_SHIFT;
+ size_t len = 0;
+
+ if (pe_size == PE_SIZE_PTE)
+ len = PAGE_SIZE;
+#ifdef CONFIG_FS_DAX_PMD
+ else if (pe_size == PE_SIZE_PMD)
+ len = HPAGE_PMD_SIZE;
+#endif
+ else
+ WARN_ON_ONCE(1);
+ err = vfs_fsync_range(vmf->vma->vm_file, start,
+ start + len - 1, 1);
+ if (err)
+ result = VM_FAULT_SIGBUS;
+ else
+ result = dax_insert_pfn_mkwrite(vmf, pe_size,
+ pfn);
+ }I think this needs to become a helper exported from the DAX code, way too much magic inside the file system as-is.