archive mirror
 help / color / mirror / Atom feed
* [PATCH] iomap: set page dirty after partial delalloc on mkwrite
@ 2018-09-28 17:39 Brian Foster
  2018-09-30 22:44 ` Christoph Hellwig
  2018-10-01  0:31 ` Dave Chinner
  0 siblings, 2 replies; 4+ messages in thread
From: Brian Foster @ 2018-09-28 17:39 UTC (permalink / raw)
  To: linux-xfs, linux-fsdevel; +Cc: Christoph Hellwig

The iomap page fault mechanism currently dirties the associated page
after the full block range of the page has been allocated. This
leaves the page susceptible to delayed allocations without ever
being set dirty on sub-page block sized filesystems.

For example, consider a page fault on a page with one preexisting
real (non-delalloc) block allocated in the middle of the page. The
first iomap_apply() iteration performs delayed allocation on the
range up to the preexisting block, the next iteration finds the
preexisting block, and the last iteration attempts to perform
delayed allocation on the range after the prexisting block to the
end of the page. If the first allocation succeeds and the final
allocation fails with -ENOSPC, iomap_apply() returns the error and
iomap_page_mkwrite() fails to dirty the page having already
performed partial delayed allocation. This eventually results in the
page being invalidated without ever converting the delayed
allocation to real blocks.

This problem is reliably reproduced by generic/083 on XFS on ppc64
systems (64k page size, 4k block size). It results in leaked
delalloc blocks on inode reclaim, which triggers an assert failure
in xfs_fs_destroy_inode() and filesystem accounting inconsistency.

Move the set_page_dirty() call from iomap_page_mkwrite() to the
actor callback, similar to how the buffer head implementation works.
The actor callback is called iff ->iomap_begin() returns success, so
ensures the page is dirtied as soon as possible after an allocation.

Signed-off-by: Brian Foster <>

This patch addresses the problem with generic/083, but I'm still in the
process of running broader testing. I wanted to get it on the list for
review in the meantime...


 fs/iomap.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/fs/iomap.c b/fs/iomap.c
index 74762b1ec233..ec15cf2ec696 100644
--- a/fs/iomap.c
+++ b/fs/iomap.c
@@ -1051,6 +1051,7 @@ iomap_page_mkwrite_actor(struct inode *inode, loff_t pos, loff_t length,
 	} else {
 		iomap_page_create(inode, page);
+		set_page_dirty(page);
 	return length;
@@ -1090,7 +1091,6 @@ int iomap_page_mkwrite(struct vm_fault *vmf, const struct iomap_ops *ops)
 		length -= ret;
-	set_page_dirty(page);

^ permalink raw reply	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2018-10-01 17:32 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2018-09-28 17:39 [PATCH] iomap: set page dirty after partial delalloc on mkwrite Brian Foster
2018-09-30 22:44 ` Christoph Hellwig
2018-10-01 10:54   ` Brian Foster
2018-10-01  0:31 ` Dave Chinner

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).