Commit 5632cca
committed
fuse: Add DLM retry workaround for iomap write failures
When the FUSE server returns -EAGAIN during write-back operations
(signaled by DLM), the write fails with an IO error. This happens
because:
1. Page invalidation holds DLM lock and needs folio lock
2. iomap write path holds folio lock and calls fuse_iomap_read_folio_range()
3. FUSE gets -EAGAIN from server (cannot acquire DLM lock - would deadlock)
4. fuse_do_readfolio() converts -EAGAIN to AOP_TRUNCATED_PAGE and unlocks folio
(This prevents the deadlock by releasing the folio lock)
5. However, iomap doesn't understand AOP_TRUNCATED_PAGE and treats it as error
6. Result: Write fails with IO error, even though it's just temporary contention
This is a FUSE-only workaround until mainline iomap gains
AOP_TRUNCATED_PAGE retry support. The solution:
1. Stack-allocate retry state in fuse_cache_write_iter()
2. Register it in fuse_conn xarray before calling iomap (indexed by task pointer)
3. When fuse_iomap_read_folio_range() sees AOP_TRUNCATED_PAGE:
- Mark the retry flag in the registered state
- Convert to -EAGAIN for iomap
4. After iomap returns, check the retry flag
5. If set, retry the entire write operation
6. Remove from xarray when done (or keep for next retry iteration)
This allows writes to succeed by retrying after the DLM lock contention
clears, rather than failing with IO error.
Technical flow showing why iov_iter is not advanced on -EAGAIN:
fuse_cache_write_iter()
total_written = 0
retry:
iomap_file_buffered_write()
iomap_write_iter() [write loop]
iomap_write_begin()
__iomap_write_begin()
Need read? → Yes
read_folio_range()
FUSE server -EAGAIN?
Yes → Set retry flag, return -EAGAIN
No → Success
Error → Break loop [iov_iter NOT advanced]
Success → Continue
copy_folio_from_iter_atomic() [Advances iov_iter]
iomap_write_end()
Advance iter.pos
Loop while more data
Update iocb->ki_pos = iter.pos
Return bytes written
if (written > 0)
total_written += written
if (retry_needed)
goto retry
return total_written
Signed-off-by: Bernd Schubert <bernd@bsbernd.com>1 parent f0cc511 commit 5632cca
3 files changed
Lines changed: 127 additions & 11 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
960 | 960 | | |
961 | 961 | | |
962 | 962 | | |
963 | | - | |
964 | | - | |
| 963 | + | |
| 964 | + | |
965 | 965 | | |
966 | 966 | | |
967 | 967 | | |
| |||
1001 | 1001 | | |
1002 | 1002 | | |
1003 | 1003 | | |
| 1004 | + | |
| 1005 | + | |
1004 | 1006 | | |
1005 | | - | |
| 1007 | + | |
| 1008 | + | |
| 1009 | + | |
| 1010 | + | |
| 1011 | + | |
| 1012 | + | |
| 1013 | + | |
| 1014 | + | |
| 1015 | + | |
| 1016 | + | |
| 1017 | + | |
| 1018 | + | |
| 1019 | + | |
| 1020 | + | |
| 1021 | + | |
| 1022 | + | |
| 1023 | + | |
| 1024 | + | |
| 1025 | + | |
| 1026 | + | |
| 1027 | + | |
| 1028 | + | |
| 1029 | + | |
| 1030 | + | |
| 1031 | + | |
| 1032 | + | |
| 1033 | + | |
| 1034 | + | |
| 1035 | + | |
| 1036 | + | |
| 1037 | + | |
| 1038 | + | |
| 1039 | + | |
| 1040 | + | |
| 1041 | + | |
| 1042 | + | |
1006 | 1043 | | |
1007 | 1044 | | |
1008 | 1045 | | |
| |||
1555 | 1592 | | |
1556 | 1593 | | |
1557 | 1594 | | |
| 1595 | + | |
| 1596 | + | |
| 1597 | + | |
| 1598 | + | |
| 1599 | + | |
| 1600 | + | |
| 1601 | + | |
| 1602 | + | |
| 1603 | + | |
| 1604 | + | |
| 1605 | + | |
| 1606 | + | |
| 1607 | + | |
| 1608 | + | |
| 1609 | + | |
| 1610 | + | |
| 1611 | + | |
| 1612 | + | |
| 1613 | + | |
| 1614 | + | |
| 1615 | + | |
| 1616 | + | |
| 1617 | + | |
| 1618 | + | |
| 1619 | + | |
| 1620 | + | |
| 1621 | + | |
| 1622 | + | |
| 1623 | + | |
| 1624 | + | |
| 1625 | + | |
| 1626 | + | |
| 1627 | + | |
| 1628 | + | |
| 1629 | + | |
| 1630 | + | |
| 1631 | + | |
| 1632 | + | |
| 1633 | + | |
| 1634 | + | |
| 1635 | + | |
| 1636 | + | |
| 1637 | + | |
| 1638 | + | |
| 1639 | + | |
| 1640 | + | |
| 1641 | + | |
| 1642 | + | |
| 1643 | + | |
| 1644 | + | |
| 1645 | + | |
| 1646 | + | |
| 1647 | + | |
| 1648 | + | |
| 1649 | + | |
| 1650 | + | |
| 1651 | + | |
| 1652 | + | |
| 1653 | + | |
| 1654 | + | |
| 1655 | + | |
| 1656 | + | |
| 1657 | + | |
1558 | 1658 | | |
1559 | 1659 | | |
1560 | 1660 | | |
| |||
1621 | 1721 | | |
1622 | 1722 | | |
1623 | 1723 | | |
1624 | | - | |
1625 | | - | |
1626 | | - | |
1627 | | - | |
1628 | | - | |
1629 | | - | |
1630 | | - | |
1631 | | - | |
| 1724 | + | |
| 1725 | + | |
| 1726 | + | |
| 1727 | + | |
| 1728 | + | |
1632 | 1729 | | |
1633 | 1730 | | |
1634 | 1731 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
639 | 639 | | |
640 | 640 | | |
641 | 641 | | |
| 642 | + | |
| 643 | + | |
| 644 | + | |
| 645 | + | |
| 646 | + | |
| 647 | + | |
| 648 | + | |
| 649 | + | |
| 650 | + | |
| 651 | + | |
| 652 | + | |
642 | 653 | | |
643 | 654 | | |
644 | 655 | | |
| |||
1022 | 1033 | | |
1023 | 1034 | | |
1024 | 1035 | | |
| 1036 | + | |
| 1037 | + | |
| 1038 | + | |
| 1039 | + | |
| 1040 | + | |
| 1041 | + | |
1025 | 1042 | | |
1026 | 1043 | | |
1027 | 1044 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
1056 | 1056 | | |
1057 | 1057 | | |
1058 | 1058 | | |
| 1059 | + | |
1059 | 1060 | | |
1060 | 1061 | | |
1061 | 1062 | | |
| |||
1109 | 1110 | | |
1110 | 1111 | | |
1111 | 1112 | | |
| 1113 | + | |
1112 | 1114 | | |
1113 | 1115 | | |
1114 | 1116 | | |
| |||
0 commit comments