Skip to content

Commit 65dd814

Browse files
Christoph HellwigDarrick J. Wong
authored andcommitted
fsdax: switch the fault handlers to use iomap_iter
Avoid the open coded calls to ->iomap_begin and ->iomap_end and call iomap_iter instead. Signed-off-by: Christoph Hellwig <[email protected]> Reviewed-by: Darrick J. Wong <[email protected]> Signed-off-by: Darrick J. Wong <[email protected]>
1 parent c243619 commit 65dd814

File tree

1 file changed

+75
-118
lines changed

1 file changed

+75
-118
lines changed

fs/dax.c

Lines changed: 75 additions & 118 deletions
Original file line numberDiff line numberDiff line change
@@ -1010,7 +1010,7 @@ static sector_t dax_iomap_sector(const struct iomap *iomap, loff_t pos)
10101010
return (iomap->addr + (pos & PAGE_MASK) - iomap->offset) >> 9;
10111011
}
10121012

1013-
static int dax_iomap_pfn(struct iomap *iomap, loff_t pos, size_t size,
1013+
static int dax_iomap_pfn(const struct iomap *iomap, loff_t pos, size_t size,
10141014
pfn_t *pfnp)
10151015
{
10161016
const sector_t sector = dax_iomap_sector(iomap, pos);
@@ -1068,7 +1068,7 @@ static vm_fault_t dax_load_hole(struct xa_state *xas,
10681068

10691069
#ifdef CONFIG_FS_DAX_PMD
10701070
static vm_fault_t dax_pmd_load_hole(struct xa_state *xas, struct vm_fault *vmf,
1071-
struct iomap *iomap, void **entry)
1071+
const struct iomap *iomap, void **entry)
10721072
{
10731073
struct address_space *mapping = vmf->vma->vm_file->f_mapping;
10741074
unsigned long pmd_addr = vmf->address & PMD_MASK;
@@ -1120,7 +1120,7 @@ static vm_fault_t dax_pmd_load_hole(struct xa_state *xas, struct vm_fault *vmf,
11201120
}
11211121
#else
11221122
static vm_fault_t dax_pmd_load_hole(struct xa_state *xas, struct vm_fault *vmf,
1123-
struct iomap *iomap, void **entry)
1123+
const struct iomap *iomap, void **entry)
11241124
{
11251125
return VM_FAULT_FALLBACK;
11261126
}
@@ -1309,7 +1309,7 @@ static vm_fault_t dax_fault_return(int error)
13091309
* flushed on write-faults (non-cow), but not read-faults.
13101310
*/
13111311
static bool dax_fault_is_synchronous(unsigned long flags,
1312-
struct vm_area_struct *vma, struct iomap *iomap)
1312+
struct vm_area_struct *vma, const struct iomap *iomap)
13131313
{
13141314
return (flags & IOMAP_WRITE) && (vma->vm_flags & VM_SYNC)
13151315
&& (iomap->flags & IOMAP_F_DIRTY);
@@ -1329,22 +1329,22 @@ static vm_fault_t dax_fault_synchronous_pfnp(pfn_t *pfnp, pfn_t pfn)
13291329
return VM_FAULT_NEEDDSYNC;
13301330
}
13311331

1332-
static vm_fault_t dax_fault_cow_page(struct vm_fault *vmf, struct iomap *iomap,
1333-
loff_t pos)
1332+
static vm_fault_t dax_fault_cow_page(struct vm_fault *vmf,
1333+
const struct iomap_iter *iter)
13341334
{
1335-
sector_t sector = dax_iomap_sector(iomap, pos);
1335+
sector_t sector = dax_iomap_sector(&iter->iomap, iter->pos);
13361336
unsigned long vaddr = vmf->address;
13371337
vm_fault_t ret;
13381338
int error = 0;
13391339

1340-
switch (iomap->type) {
1340+
switch (iter->iomap.type) {
13411341
case IOMAP_HOLE:
13421342
case IOMAP_UNWRITTEN:
13431343
clear_user_highpage(vmf->cow_page, vaddr);
13441344
break;
13451345
case IOMAP_MAPPED:
1346-
error = copy_cow_page_dax(iomap->bdev, iomap->dax_dev, sector,
1347-
vmf->cow_page, vaddr);
1346+
error = copy_cow_page_dax(iter->iomap.bdev, iter->iomap.dax_dev,
1347+
sector, vmf->cow_page, vaddr);
13481348
break;
13491349
default:
13501350
WARN_ON_ONCE(1);
@@ -1363,29 +1363,31 @@ static vm_fault_t dax_fault_cow_page(struct vm_fault *vmf, struct iomap *iomap,
13631363
}
13641364

13651365
/**
1366-
* dax_fault_actor - Common actor to handle pfn insertion in PTE/PMD fault.
1366+
* dax_fault_iter - Common actor to handle pfn insertion in PTE/PMD fault.
13671367
* @vmf: vm fault instance
1368+
* @iter: iomap iter
13681369
* @pfnp: pfn to be returned
13691370
* @xas: the dax mapping tree of a file
13701371
* @entry: an unlocked dax entry to be inserted
13711372
* @pmd: distinguish whether it is a pmd fault
1372-
* @flags: iomap flags
1373-
* @iomap: from iomap_begin()
1374-
* @srcmap: from iomap_begin(), not equal to iomap if it is a CoW
13751373
*/
1376-
static vm_fault_t dax_fault_actor(struct vm_fault *vmf, pfn_t *pfnp,
1377-
struct xa_state *xas, void **entry, bool pmd,
1378-
unsigned int flags, struct iomap *iomap, struct iomap *srcmap)
1374+
static vm_fault_t dax_fault_iter(struct vm_fault *vmf,
1375+
const struct iomap_iter *iter, pfn_t *pfnp,
1376+
struct xa_state *xas, void **entry, bool pmd)
13791377
{
13801378
struct address_space *mapping = vmf->vma->vm_file->f_mapping;
1379+
const struct iomap *iomap = &iter->iomap;
13811380
size_t size = pmd ? PMD_SIZE : PAGE_SIZE;
13821381
loff_t pos = (loff_t)xas->xa_index << PAGE_SHIFT;
13831382
bool write = vmf->flags & FAULT_FLAG_WRITE;
1384-
bool sync = dax_fault_is_synchronous(flags, vmf->vma, iomap);
1383+
bool sync = dax_fault_is_synchronous(iter->flags, vmf->vma, iomap);
13851384
unsigned long entry_flags = pmd ? DAX_PMD : 0;
13861385
int err = 0;
13871386
pfn_t pfn;
13881387

1388+
if (!pmd && vmf->cow_page)
1389+
return dax_fault_cow_page(vmf, iter);
1390+
13891391
/* if we are reading UNWRITTEN and HOLE, return a hole. */
13901392
if (!write &&
13911393
(iomap->type == IOMAP_UNWRITTEN || iomap->type == IOMAP_HOLE)) {
@@ -1399,7 +1401,7 @@ static vm_fault_t dax_fault_actor(struct vm_fault *vmf, pfn_t *pfnp,
13991401
return pmd ? VM_FAULT_FALLBACK : VM_FAULT_SIGBUS;
14001402
}
14011403

1402-
err = dax_iomap_pfn(iomap, pos, size, &pfn);
1404+
err = dax_iomap_pfn(&iter->iomap, pos, size, &pfn);
14031405
if (err)
14041406
return pmd ? VM_FAULT_FALLBACK : dax_fault_return(err);
14051407

@@ -1422,32 +1424,31 @@ static vm_fault_t dax_fault_actor(struct vm_fault *vmf, pfn_t *pfnp,
14221424
static vm_fault_t dax_iomap_pte_fault(struct vm_fault *vmf, pfn_t *pfnp,
14231425
int *iomap_errp, const struct iomap_ops *ops)
14241426
{
1425-
struct vm_area_struct *vma = vmf->vma;
1426-
struct address_space *mapping = vma->vm_file->f_mapping;
1427+
struct address_space *mapping = vmf->vma->vm_file->f_mapping;
14271428
XA_STATE(xas, &mapping->i_pages, vmf->pgoff);
1428-
struct inode *inode = mapping->host;
1429-
loff_t pos = (loff_t)vmf->pgoff << PAGE_SHIFT;
1430-
struct iomap iomap = { .type = IOMAP_HOLE };
1431-
struct iomap srcmap = { .type = IOMAP_HOLE };
1432-
unsigned flags = IOMAP_FAULT;
1433-
int error;
1434-
bool write = vmf->flags & FAULT_FLAG_WRITE;
1435-
vm_fault_t ret = 0, major = 0;
1429+
struct iomap_iter iter = {
1430+
.inode = mapping->host,
1431+
.pos = (loff_t)vmf->pgoff << PAGE_SHIFT,
1432+
.len = PAGE_SIZE,
1433+
.flags = IOMAP_FAULT,
1434+
};
1435+
vm_fault_t ret = 0;
14361436
void *entry;
1437+
int error;
14371438

1438-
trace_dax_pte_fault(inode, vmf, ret);
1439+
trace_dax_pte_fault(iter.inode, vmf, ret);
14391440
/*
14401441
* Check whether offset isn't beyond end of file now. Caller is supposed
14411442
* to hold locks serializing us with truncate / punch hole so this is
14421443
* a reliable test.
14431444
*/
1444-
if (pos >= i_size_read(inode)) {
1445+
if (iter.pos >= i_size_read(iter.inode)) {
14451446
ret = VM_FAULT_SIGBUS;
14461447
goto out;
14471448
}
14481449

1449-
if (write && !vmf->cow_page)
1450-
flags |= IOMAP_WRITE;
1450+
if ((vmf->flags & FAULT_FLAG_WRITE) && !vmf->cow_page)
1451+
iter.flags |= IOMAP_WRITE;
14511452

14521453
entry = grab_mapping_entry(&xas, mapping, 0);
14531454
if (xa_is_internal(entry)) {
@@ -1466,59 +1467,34 @@ static vm_fault_t dax_iomap_pte_fault(struct vm_fault *vmf, pfn_t *pfnp,
14661467
goto unlock_entry;
14671468
}
14681469

1469-
/*
1470-
* Note that we don't bother to use iomap_iter here: DAX required
1471-
* the file system block size to be equal the page size, which means
1472-
* that we never have to deal with more than a single extent here.
1473-
*/
1474-
error = ops->iomap_begin(inode, pos, PAGE_SIZE, flags, &iomap, &srcmap);
1475-
if (iomap_errp)
1476-
*iomap_errp = error;
1477-
if (error) {
1478-
ret = dax_fault_return(error);
1479-
goto unlock_entry;
1480-
}
1481-
if (WARN_ON_ONCE(iomap.offset + iomap.length < pos + PAGE_SIZE)) {
1482-
ret = VM_FAULT_SIGBUS; /* fs corruption? */
1483-
goto finish_iomap;
1484-
}
1485-
1486-
if (vmf->cow_page) {
1487-
ret = dax_fault_cow_page(vmf, &iomap, pos);
1488-
goto finish_iomap;
1489-
}
1470+
while ((error = iomap_iter(&iter, ops)) > 0) {
1471+
if (WARN_ON_ONCE(iomap_length(&iter) < PAGE_SIZE)) {
1472+
iter.processed = -EIO; /* fs corruption? */
1473+
continue;
1474+
}
14901475

1491-
ret = dax_fault_actor(vmf, pfnp, &xas, &entry, false, flags,
1492-
&iomap, &srcmap);
1493-
if (ret == VM_FAULT_SIGBUS)
1494-
goto finish_iomap;
1476+
ret = dax_fault_iter(vmf, &iter, pfnp, &xas, &entry, false);
1477+
if (ret != VM_FAULT_SIGBUS &&
1478+
(iter.iomap.flags & IOMAP_F_NEW)) {
1479+
count_vm_event(PGMAJFAULT);
1480+
count_memcg_event_mm(vmf->vma->vm_mm, PGMAJFAULT);
1481+
ret |= VM_FAULT_MAJOR;
1482+
}
14951483

1496-
/* read/write MAPPED, CoW UNWRITTEN */
1497-
if (iomap.flags & IOMAP_F_NEW) {
1498-
count_vm_event(PGMAJFAULT);
1499-
count_memcg_event_mm(vma->vm_mm, PGMAJFAULT);
1500-
major = VM_FAULT_MAJOR;
1484+
if (!(ret & VM_FAULT_ERROR))
1485+
iter.processed = PAGE_SIZE;
15011486
}
15021487

1503-
finish_iomap:
1504-
if (ops->iomap_end) {
1505-
int copied = PAGE_SIZE;
1488+
if (iomap_errp)
1489+
*iomap_errp = error;
1490+
if (!ret && error)
1491+
ret = dax_fault_return(error);
15061492

1507-
if (ret & VM_FAULT_ERROR)
1508-
copied = 0;
1509-
/*
1510-
* The fault is done by now and there's no way back (other
1511-
* thread may be already happily using PTE we have installed).
1512-
* Just ignore error from ->iomap_end since we cannot do much
1513-
* with it.
1514-
*/
1515-
ops->iomap_end(inode, pos, PAGE_SIZE, copied, flags, &iomap);
1516-
}
15171493
unlock_entry:
15181494
dax_unlock_entry(&xas, entry);
15191495
out:
1520-
trace_dax_pte_fault_done(inode, vmf, ret);
1521-
return ret | major;
1496+
trace_dax_pte_fault_done(iter.inode, vmf, ret);
1497+
return ret;
15221498
}
15231499

15241500
#ifdef CONFIG_FS_DAX_PMD
@@ -1558,28 +1534,29 @@ static bool dax_fault_check_fallback(struct vm_fault *vmf, struct xa_state *xas,
15581534
static vm_fault_t dax_iomap_pmd_fault(struct vm_fault *vmf, pfn_t *pfnp,
15591535
const struct iomap_ops *ops)
15601536
{
1561-
struct vm_area_struct *vma = vmf->vma;
1562-
struct address_space *mapping = vma->vm_file->f_mapping;
1537+
struct address_space *mapping = vmf->vma->vm_file->f_mapping;
15631538
XA_STATE_ORDER(xas, &mapping->i_pages, vmf->pgoff, PMD_ORDER);
1564-
bool write = vmf->flags & FAULT_FLAG_WRITE;
1565-
unsigned int flags = (write ? IOMAP_WRITE : 0) | IOMAP_FAULT;
1566-
struct inode *inode = mapping->host;
1539+
struct iomap_iter iter = {
1540+
.inode = mapping->host,
1541+
.len = PMD_SIZE,
1542+
.flags = IOMAP_FAULT,
1543+
};
15671544
vm_fault_t ret = VM_FAULT_FALLBACK;
1568-
struct iomap iomap = { .type = IOMAP_HOLE };
1569-
struct iomap srcmap = { .type = IOMAP_HOLE };
15701545
pgoff_t max_pgoff;
15711546
void *entry;
1572-
loff_t pos;
15731547
int error;
15741548

1549+
if (vmf->flags & FAULT_FLAG_WRITE)
1550+
iter.flags |= IOMAP_WRITE;
1551+
15751552
/*
15761553
* Check whether offset isn't beyond end of file now. Caller is
15771554
* supposed to hold locks serializing us with truncate / punch hole so
15781555
* this is a reliable test.
15791556
*/
1580-
max_pgoff = DIV_ROUND_UP(i_size_read(inode), PAGE_SIZE);
1557+
max_pgoff = DIV_ROUND_UP(i_size_read(iter.inode), PAGE_SIZE);
15811558

1582-
trace_dax_pmd_fault(inode, vmf, max_pgoff, 0);
1559+
trace_dax_pmd_fault(iter.inode, vmf, max_pgoff, 0);
15831560

15841561
if (xas.xa_index >= max_pgoff) {
15851562
ret = VM_FAULT_SIGBUS;
@@ -1613,45 +1590,25 @@ static vm_fault_t dax_iomap_pmd_fault(struct vm_fault *vmf, pfn_t *pfnp,
16131590
goto unlock_entry;
16141591
}
16151592

1616-
/*
1617-
* Note that we don't use iomap_iter here. We aren't doing I/O, only
1618-
* setting up a mapping, so really we're using iomap_begin() as a way
1619-
* to look up our filesystem block.
1620-
*/
1621-
pos = (loff_t)xas.xa_index << PAGE_SHIFT;
1622-
error = ops->iomap_begin(inode, pos, PMD_SIZE, flags, &iomap, &srcmap);
1623-
if (error)
1624-
goto unlock_entry;
1625-
1626-
if (iomap.offset + iomap.length < pos + PMD_SIZE)
1627-
goto finish_iomap;
1593+
iter.pos = (loff_t)xas.xa_index << PAGE_SHIFT;
1594+
while ((error = iomap_iter(&iter, ops)) > 0) {
1595+
if (iomap_length(&iter) < PMD_SIZE)
1596+
continue; /* actually breaks out of the loop */
16281597

1629-
ret = dax_fault_actor(vmf, pfnp, &xas, &entry, true, flags,
1630-
&iomap, &srcmap);
1631-
1632-
finish_iomap:
1633-
if (ops->iomap_end) {
1634-
int copied = PMD_SIZE;
1635-
1636-
if (ret == VM_FAULT_FALLBACK)
1637-
copied = 0;
1638-
/*
1639-
* The fault is done by now and there's no way back (other
1640-
* thread may be already happily using PMD we have installed).
1641-
* Just ignore error from ->iomap_end since we cannot do much
1642-
* with it.
1643-
*/
1644-
ops->iomap_end(inode, pos, PMD_SIZE, copied, flags, &iomap);
1598+
ret = dax_fault_iter(vmf, &iter, pfnp, &xas, &entry, true);
1599+
if (ret != VM_FAULT_FALLBACK)
1600+
iter.processed = PMD_SIZE;
16451601
}
1602+
16461603
unlock_entry:
16471604
dax_unlock_entry(&xas, entry);
16481605
fallback:
16491606
if (ret == VM_FAULT_FALLBACK) {
1650-
split_huge_pmd(vma, vmf->pmd, vmf->address);
1607+
split_huge_pmd(vmf->vma, vmf->pmd, vmf->address);
16511608
count_vm_event(THP_FAULT_FALLBACK);
16521609
}
16531610
out:
1654-
trace_dax_pmd_fault_done(inode, vmf, max_pgoff, ret);
1611+
trace_dax_pmd_fault_done(iter.inode, vmf, max_pgoff, ret);
16551612
return ret;
16561613
}
16571614
#else

0 commit comments

Comments
 (0)