aboutsummaryrefslogtreecommitdiffstats
path: root/fs/dax.c
diff options
context:
space:
mode:
authorSouptick Joarder <jrdr.linux@gmail.com>2018-06-07 20:04:29 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2018-06-07 20:34:33 -0400
commitab77dab46210bb630e06c6803c5d84074bacd351 (patch)
tree1b0c7f6899d1438d11fa3fab5353318539aafd96 /fs/dax.c
parent3036bc45364f98515a2c446d7fac2c34dcfbeff4 (diff)
fs/dax.c: use new return type vm_fault_t
Use new return type vm_fault_t for fault handler. For now, this is just documenting that the function returns a VM_FAULT value rather than an errno. Once all instances are converted, vm_fault_t will become a distinct type. commit 1c8f422059ae ("mm: change return type to vm_fault_t") There was an existing bug inside dax_load_hole() if vm_insert_mixed had failed to allocate a page table, we'd return VM_FAULT_NOPAGE instead of VM_FAULT_OOM. With new vmf_insert_mixed() this issue is addressed. vm_insert_mixed_mkwrite has inefficiency when it returns an error value, driver has to convert it to vm_fault_t type. With new vmf_insert_mixed_mkwrite() this limitation will be addressed. Link: http://lkml.kernel.org/r/20180510181121.GA15239@jordon-HP-15-Notebook-PC Signed-off-by: Souptick Joarder <jrdr.linux@gmail.com> Reviewed-by: Jan Kara <jack@suse.cz> Reviewed-by: Matthew Wilcox <mawilcox@microsoft.com> Reviewed-by: Ross Zwisler <ross.zwisler@linux.intel.com> Cc: Alexander Viro <viro@zeniv.linux.org.uk> Cc: Dan Williams <dan.j.williams@intel.com> Cc: Michal Hocko <mhocko@suse.com> Cc: "Kirill A. Shutemov" <kirill.shutemov@linux.intel.com> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'fs/dax.c')
-rw-r--r--fs/dax.c78
1 files changed, 37 insertions, 41 deletions
diff --git a/fs/dax.c b/fs/dax.c
index aa86d9f971a4..08656a2f2aa6 100644
--- a/fs/dax.c
+++ b/fs/dax.c
@@ -905,12 +905,12 @@ out:
905 * If this page is ever written to we will re-fault and change the mapping to 905 * If this page is ever written to we will re-fault and change the mapping to
906 * point to real DAX storage instead. 906 * point to real DAX storage instead.
907 */ 907 */
908static int dax_load_hole(struct address_space *mapping, void *entry, 908static vm_fault_t dax_load_hole(struct address_space *mapping, void *entry,
909 struct vm_fault *vmf) 909 struct vm_fault *vmf)
910{ 910{
911 struct inode *inode = mapping->host; 911 struct inode *inode = mapping->host;
912 unsigned long vaddr = vmf->address; 912 unsigned long vaddr = vmf->address;
913 int ret = VM_FAULT_NOPAGE; 913 vm_fault_t ret = VM_FAULT_NOPAGE;
914 struct page *zero_page; 914 struct page *zero_page;
915 void *entry2; 915 void *entry2;
916 pfn_t pfn; 916 pfn_t pfn;
@@ -929,7 +929,7 @@ static int dax_load_hole(struct address_space *mapping, void *entry,
929 goto out; 929 goto out;
930 } 930 }
931 931
932 vm_insert_mixed(vmf->vma, vaddr, pfn); 932 ret = vmf_insert_mixed(vmf->vma, vaddr, pfn);
933out: 933out:
934 trace_dax_load_hole(inode, vmf, ret); 934 trace_dax_load_hole(inode, vmf, ret);
935 return ret; 935 return ret;
@@ -1112,7 +1112,7 @@ dax_iomap_rw(struct kiocb *iocb, struct iov_iter *iter,
1112} 1112}
1113EXPORT_SYMBOL_GPL(dax_iomap_rw); 1113EXPORT_SYMBOL_GPL(dax_iomap_rw);
1114 1114
1115static int dax_fault_return(int error) 1115static vm_fault_t dax_fault_return(int error)
1116{ 1116{
1117 if (error == 0) 1117 if (error == 0)
1118 return VM_FAULT_NOPAGE; 1118 return VM_FAULT_NOPAGE;
@@ -1132,7 +1132,7 @@ static bool dax_fault_is_synchronous(unsigned long flags,
1132 && (iomap->flags & IOMAP_F_DIRTY); 1132 && (iomap->flags & IOMAP_F_DIRTY);
1133} 1133}
1134 1134
1135static int dax_iomap_pte_fault(struct vm_fault *vmf, pfn_t *pfnp, 1135static vm_fault_t dax_iomap_pte_fault(struct vm_fault *vmf, pfn_t *pfnp,
1136 int *iomap_errp, const struct iomap_ops *ops) 1136 int *iomap_errp, const struct iomap_ops *ops)
1137{ 1137{
1138 struct vm_area_struct *vma = vmf->vma; 1138 struct vm_area_struct *vma = vmf->vma;
@@ -1145,18 +1145,18 @@ static int dax_iomap_pte_fault(struct vm_fault *vmf, pfn_t *pfnp,
1145 int error, major = 0; 1145 int error, major = 0;
1146 bool write = vmf->flags & FAULT_FLAG_WRITE; 1146 bool write = vmf->flags & FAULT_FLAG_WRITE;
1147 bool sync; 1147 bool sync;
1148 int vmf_ret = 0; 1148 vm_fault_t ret = 0;
1149 void *entry; 1149 void *entry;
1150 pfn_t pfn; 1150 pfn_t pfn;
1151 1151
1152 trace_dax_pte_fault(inode, vmf, vmf_ret); 1152 trace_dax_pte_fault(inode, vmf, ret);
1153 /* 1153 /*
1154 * Check whether offset isn't beyond end of file now. Caller is supposed 1154 * Check whether offset isn't beyond end of file now. Caller is supposed
1155 * to hold locks serializing us with truncate / punch hole so this is 1155 * to hold locks serializing us with truncate / punch hole so this is
1156 * a reliable test. 1156 * a reliable test.
1157 */ 1157 */
1158 if (pos >= i_size_read(inode)) { 1158 if (pos >= i_size_read(inode)) {
1159 vmf_ret = VM_FAULT_SIGBUS; 1159 ret = VM_FAULT_SIGBUS;
1160 goto out; 1160 goto out;
1161 } 1161 }
1162 1162
@@ -1165,7 +1165,7 @@ static int dax_iomap_pte_fault(struct vm_fault *vmf, pfn_t *pfnp,
1165 1165
1166 entry = grab_mapping_entry(mapping, vmf->pgoff, 0); 1166 entry = grab_mapping_entry(mapping, vmf->pgoff, 0);
1167 if (IS_ERR(entry)) { 1167 if (IS_ERR(entry)) {
1168 vmf_ret = dax_fault_return(PTR_ERR(entry)); 1168 ret = dax_fault_return(PTR_ERR(entry));
1169 goto out; 1169 goto out;
1170 } 1170 }
1171 1171
@@ -1176,7 +1176,7 @@ static int dax_iomap_pte_fault(struct vm_fault *vmf, pfn_t *pfnp,
1176 * retried. 1176 * retried.
1177 */ 1177 */
1178 if (pmd_trans_huge(*vmf->pmd) || pmd_devmap(*vmf->pmd)) { 1178 if (pmd_trans_huge(*vmf->pmd) || pmd_devmap(*vmf->pmd)) {
1179 vmf_ret = VM_FAULT_NOPAGE; 1179 ret = VM_FAULT_NOPAGE;
1180 goto unlock_entry; 1180 goto unlock_entry;
1181 } 1181 }
1182 1182
@@ -1189,7 +1189,7 @@ static int dax_iomap_pte_fault(struct vm_fault *vmf, pfn_t *pfnp,
1189 if (iomap_errp) 1189 if (iomap_errp)
1190 *iomap_errp = error; 1190 *iomap_errp = error;
1191 if (error) { 1191 if (error) {
1192 vmf_ret = dax_fault_return(error); 1192 ret = dax_fault_return(error);
1193 goto unlock_entry; 1193 goto unlock_entry;
1194 } 1194 }
1195 if (WARN_ON_ONCE(iomap.offset + iomap.length < pos + PAGE_SIZE)) { 1195 if (WARN_ON_ONCE(iomap.offset + iomap.length < pos + PAGE_SIZE)) {
@@ -1219,9 +1219,9 @@ static int dax_iomap_pte_fault(struct vm_fault *vmf, pfn_t *pfnp,
1219 goto error_finish_iomap; 1219 goto error_finish_iomap;
1220 1220
1221 __SetPageUptodate(vmf->cow_page); 1221 __SetPageUptodate(vmf->cow_page);
1222 vmf_ret = finish_fault(vmf); 1222 ret = finish_fault(vmf);
1223 if (!vmf_ret) 1223 if (!ret)
1224 vmf_ret = VM_FAULT_DONE_COW; 1224 ret = VM_FAULT_DONE_COW;
1225 goto finish_iomap; 1225 goto finish_iomap;
1226 } 1226 }
1227 1227
@@ -1257,23 +1257,20 @@ static int dax_iomap_pte_fault(struct vm_fault *vmf, pfn_t *pfnp,
1257 goto error_finish_iomap; 1257 goto error_finish_iomap;
1258 } 1258 }
1259 *pfnp = pfn; 1259 *pfnp = pfn;
1260 vmf_ret = VM_FAULT_NEEDDSYNC | major; 1260 ret = VM_FAULT_NEEDDSYNC | major;
1261 goto finish_iomap; 1261 goto finish_iomap;
1262 } 1262 }
1263 trace_dax_insert_mapping(inode, vmf, entry); 1263 trace_dax_insert_mapping(inode, vmf, entry);
1264 if (write) 1264 if (write)
1265 error = vm_insert_mixed_mkwrite(vma, vaddr, pfn); 1265 ret = vmf_insert_mixed_mkwrite(vma, vaddr, pfn);
1266 else 1266 else
1267 error = vm_insert_mixed(vma, vaddr, pfn); 1267 ret = vmf_insert_mixed(vma, vaddr, pfn);
1268 1268
1269 /* -EBUSY is fine, somebody else faulted on the same PTE */ 1269 goto finish_iomap;
1270 if (error == -EBUSY)
1271 error = 0;
1272 break;
1273 case IOMAP_UNWRITTEN: 1270 case IOMAP_UNWRITTEN:
1274 case IOMAP_HOLE: 1271 case IOMAP_HOLE:
1275 if (!write) { 1272 if (!write) {
1276 vmf_ret = dax_load_hole(mapping, entry, vmf); 1273 ret = dax_load_hole(mapping, entry, vmf);
1277 goto finish_iomap; 1274 goto finish_iomap;
1278 } 1275 }
1279 /*FALLTHRU*/ 1276 /*FALLTHRU*/
@@ -1284,12 +1281,12 @@ static int dax_iomap_pte_fault(struct vm_fault *vmf, pfn_t *pfnp,
1284 } 1281 }
1285 1282
1286 error_finish_iomap: 1283 error_finish_iomap:
1287 vmf_ret = dax_fault_return(error) | major; 1284 ret = dax_fault_return(error);
1288 finish_iomap: 1285 finish_iomap:
1289 if (ops->iomap_end) { 1286 if (ops->iomap_end) {
1290 int copied = PAGE_SIZE; 1287 int copied = PAGE_SIZE;
1291 1288
1292 if (vmf_ret & VM_FAULT_ERROR) 1289 if (ret & VM_FAULT_ERROR)
1293 copied = 0; 1290 copied = 0;
1294 /* 1291 /*
1295 * The fault is done by now and there's no way back (other 1292 * The fault is done by now and there's no way back (other
@@ -1302,12 +1299,12 @@ static int dax_iomap_pte_fault(struct vm_fault *vmf, pfn_t *pfnp,
1302 unlock_entry: 1299 unlock_entry:
1303 put_locked_mapping_entry(mapping, vmf->pgoff); 1300 put_locked_mapping_entry(mapping, vmf->pgoff);
1304 out: 1301 out:
1305 trace_dax_pte_fault_done(inode, vmf, vmf_ret); 1302 trace_dax_pte_fault_done(inode, vmf, ret);
1306 return vmf_ret; 1303 return ret | major;
1307} 1304}
1308 1305
1309#ifdef CONFIG_FS_DAX_PMD 1306#ifdef CONFIG_FS_DAX_PMD
1310static int dax_pmd_load_hole(struct vm_fault *vmf, struct iomap *iomap, 1307static vm_fault_t dax_pmd_load_hole(struct vm_fault *vmf, struct iomap *iomap,
1311 void *entry) 1308 void *entry)
1312{ 1309{
1313 struct address_space *mapping = vmf->vma->vm_file->f_mapping; 1310 struct address_space *mapping = vmf->vma->vm_file->f_mapping;
@@ -1348,7 +1345,7 @@ fallback:
1348 return VM_FAULT_FALLBACK; 1345 return VM_FAULT_FALLBACK;
1349} 1346}
1350 1347
1351static int dax_iomap_pmd_fault(struct vm_fault *vmf, pfn_t *pfnp, 1348static vm_fault_t dax_iomap_pmd_fault(struct vm_fault *vmf, pfn_t *pfnp,
1352 const struct iomap_ops *ops) 1349 const struct iomap_ops *ops)
1353{ 1350{
1354 struct vm_area_struct *vma = vmf->vma; 1351 struct vm_area_struct *vma = vmf->vma;
@@ -1358,7 +1355,7 @@ static int dax_iomap_pmd_fault(struct vm_fault *vmf, pfn_t *pfnp,
1358 bool sync; 1355 bool sync;
1359 unsigned int iomap_flags = (write ? IOMAP_WRITE : 0) | IOMAP_FAULT; 1356 unsigned int iomap_flags = (write ? IOMAP_WRITE : 0) | IOMAP_FAULT;
1360 struct inode *inode = mapping->host; 1357 struct inode *inode = mapping->host;
1361 int result = VM_FAULT_FALLBACK; 1358 vm_fault_t result = VM_FAULT_FALLBACK;
1362 struct iomap iomap = { 0 }; 1359 struct iomap iomap = { 0 };
1363 pgoff_t max_pgoff, pgoff; 1360 pgoff_t max_pgoff, pgoff;
1364 void *entry; 1361 void *entry;
@@ -1509,7 +1506,7 @@ out:
1509 return result; 1506 return result;
1510} 1507}
1511#else 1508#else
1512static int dax_iomap_pmd_fault(struct vm_fault *vmf, pfn_t *pfnp, 1509static vm_fault_t dax_iomap_pmd_fault(struct vm_fault *vmf, pfn_t *pfnp,
1513 const struct iomap_ops *ops) 1510 const struct iomap_ops *ops)
1514{ 1511{
1515 return VM_FAULT_FALLBACK; 1512 return VM_FAULT_FALLBACK;
@@ -1529,7 +1526,7 @@ static int dax_iomap_pmd_fault(struct vm_fault *vmf, pfn_t *pfnp,
1529 * has done all the necessary locking for page fault to proceed 1526 * has done all the necessary locking for page fault to proceed
1530 * successfully. 1527 * successfully.
1531 */ 1528 */
1532int dax_iomap_fault(struct vm_fault *vmf, enum page_entry_size pe_size, 1529vm_fault_t dax_iomap_fault(struct vm_fault *vmf, enum page_entry_size pe_size,
1533 pfn_t *pfnp, int *iomap_errp, const struct iomap_ops *ops) 1530 pfn_t *pfnp, int *iomap_errp, const struct iomap_ops *ops)
1534{ 1531{
1535 switch (pe_size) { 1532 switch (pe_size) {
@@ -1553,14 +1550,14 @@ EXPORT_SYMBOL_GPL(dax_iomap_fault);
1553 * DAX file. It takes care of marking corresponding radix tree entry as dirty 1550 * DAX file. It takes care of marking corresponding radix tree entry as dirty
1554 * as well. 1551 * as well.
1555 */ 1552 */
1556static int dax_insert_pfn_mkwrite(struct vm_fault *vmf, 1553static vm_fault_t dax_insert_pfn_mkwrite(struct vm_fault *vmf,
1557 enum page_entry_size pe_size, 1554 enum page_entry_size pe_size,
1558 pfn_t pfn) 1555 pfn_t pfn)
1559{ 1556{
1560 struct address_space *mapping = vmf->vma->vm_file->f_mapping; 1557 struct address_space *mapping = vmf->vma->vm_file->f_mapping;
1561 void *entry, **slot; 1558 void *entry, **slot;
1562 pgoff_t index = vmf->pgoff; 1559 pgoff_t index = vmf->pgoff;
1563 int vmf_ret, error; 1560 vm_fault_t ret;
1564 1561
1565 xa_lock_irq(&mapping->i_pages); 1562 xa_lock_irq(&mapping->i_pages);
1566 entry = get_unlocked_mapping_entry(mapping, index, &slot); 1563 entry = get_unlocked_mapping_entry(mapping, index, &slot);
@@ -1579,21 +1576,20 @@ static int dax_insert_pfn_mkwrite(struct vm_fault *vmf,
1579 xa_unlock_irq(&mapping->i_pages); 1576 xa_unlock_irq(&mapping->i_pages);
1580 switch (pe_size) { 1577 switch (pe_size) {
1581 case PE_SIZE_PTE: 1578 case PE_SIZE_PTE:
1582 error = vm_insert_mixed_mkwrite(vmf->vma, vmf->address, pfn); 1579 ret = vmf_insert_mixed_mkwrite(vmf->vma, vmf->address, pfn);
1583 vmf_ret = dax_fault_return(error);
1584 break; 1580 break;
1585#ifdef CONFIG_FS_DAX_PMD 1581#ifdef CONFIG_FS_DAX_PMD
1586 case PE_SIZE_PMD: 1582 case PE_SIZE_PMD:
1587 vmf_ret = vmf_insert_pfn_pmd(vmf->vma, vmf->address, vmf->pmd, 1583 ret = vmf_insert_pfn_pmd(vmf->vma, vmf->address, vmf->pmd,
1588 pfn, true); 1584 pfn, true);
1589 break; 1585 break;
1590#endif 1586#endif
1591 default: 1587 default:
1592 vmf_ret = VM_FAULT_FALLBACK; 1588 ret = VM_FAULT_FALLBACK;
1593 } 1589 }
1594 put_locked_mapping_entry(mapping, index); 1590 put_locked_mapping_entry(mapping, index);
1595 trace_dax_insert_pfn_mkwrite(mapping->host, vmf, vmf_ret); 1591 trace_dax_insert_pfn_mkwrite(mapping->host, vmf, ret);
1596 return vmf_ret; 1592 return ret;
1597} 1593}
1598 1594
1599/** 1595/**
@@ -1606,8 +1602,8 @@ static int dax_insert_pfn_mkwrite(struct vm_fault *vmf,
1606 * stored persistently on the media and handles inserting of appropriate page 1602 * stored persistently on the media and handles inserting of appropriate page
1607 * table entry. 1603 * table entry.
1608 */ 1604 */
1609int dax_finish_sync_fault(struct vm_fault *vmf, enum page_entry_size pe_size, 1605vm_fault_t dax_finish_sync_fault(struct vm_fault *vmf,
1610 pfn_t pfn) 1606 enum page_entry_size pe_size, pfn_t pfn)
1611{ 1607{
1612 int err; 1608 int err;
1613 loff_t start = ((loff_t)vmf->pgoff) << PAGE_SHIFT; 1609 loff_t start = ((loff_t)vmf->pgoff) << PAGE_SHIFT;