summaryrefslogtreecommitdiff
path: root/include
diff options
context:
space:
mode:
authorBrian Foster <bfoster@redhat.com>2020-10-29 14:30:48 -0700
committerDarrick J. Wong <darrick.wong@oracle.com>2020-11-04 08:52:46 -0800
commit763e4cdc0f6d5cea45c896fef67f7be4bdefcca7 (patch)
treed25be46ce7b766d673986ac041d80a7c33bb34d3 /include
parent869ae85dae64b5540e4362d7fe4cd520e10ec05c (diff)
iomap: support partial page discard on writeback block mapping failure
iomap writeback mapping failure only calls into ->discard_page() if the current page has not been added to the ioend. Accordingly, the XFS callback assumes a full page discard and invalidation. This is problematic for sub-page block size filesystems where some portion of a page might have been mapped successfully before a failure to map a delalloc block occurs. ->discard_page() is not called in that error scenario and the bio is explicitly failed by iomap via the error return from ->prepare_ioend(). As a result, the filesystem leaks delalloc blocks and corrupts the filesystem block counters. Since XFS is the only user of ->discard_page(), tweak the semantics to invoke the callback unconditionally on mapping errors and provide the file offset that failed to map. Update xfs_discard_page() to discard the corresponding portion of the file and pass the range along to iomap_invalidatepage(). The latter already properly handles both full and sub-page scenarios by not changing any iomap or page state on sub-page invalidations. Signed-off-by: Brian Foster <bfoster@redhat.com> Reviewed-by: Christoph Hellwig <hch@lst.de> Reviewed-by: Darrick J. Wong <darrick.wong@oracle.com> Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>
Diffstat (limited to 'include')
-rw-r--r--include/linux/iomap.h2
1 files changed, 1 insertions, 1 deletions
diff --git a/include/linux/iomap.h b/include/linux/iomap.h
index 172b3397a1a3..5bd3cac4df9c 100644
--- a/include/linux/iomap.h
+++ b/include/linux/iomap.h
@@ -221,7 +221,7 @@ struct iomap_writeback_ops {
* Optional, allows the file system to discard state on a page where
* we failed to submit any I/O.
*/
- void (*discard_page)(struct page *page);
+ void (*discard_page)(struct page *page, loff_t fileoff);
};
struct iomap_writepage_ctx {