From 353448f3ea42e5deec298d6d2c577ade7028b7fd Mon Sep 17 00:00:00 2001 From: Kent Overstreet Date: Sun, 23 Oct 2022 22:01:50 -0400 Subject: [PATCH] bcachefs: Fix buffered write path for generic/275 Per fstests generic/275, on -ENOSPC we're supposed write until the filesystem is full - i.e. do a partial write instead of failing the full write. This is a partial fix for the buffered write path: we'll still fail on a page boundary. Signed-off-by: Kent Overstreet --- fs/bcachefs/fs-io.c | 19 +++++++++++++++---- 1 file changed, 15 insertions(+), 4 deletions(-) diff --git a/fs/bcachefs/fs-io.c b/fs/bcachefs/fs-io.c index b1d53290f6bac..49b0fb6522e70 100644 --- a/fs/bcachefs/fs-io.c +++ b/fs/bcachefs/fs-io.c @@ -1656,10 +1656,21 @@ static int __bch2_buffered_write(struct bch_inode_info *inode, goto out; } + /* + * XXX: per POSIX and fstests generic/275, on -ENOSPC we're + * supposed to write as much as we have disk space for. + * + * On failure here we should still write out a partial page if + * we aren't completely out of disk space - we don't do that + * yet: + */ ret = bch2_page_reservation_get(c, inode, page, &res, pg_offset, pg_len); - if (ret) - goto out; + if (unlikely(ret)) { + if (!reserved) + goto out; + break; + } reserved += pg_len; } @@ -1668,10 +1679,10 @@ static int __bch2_buffered_write(struct bch_inode_info *inode, for (i = 0; i < nr_pages; i++) flush_dcache_page(pages[i]); - while (copied < len) { + while (copied < reserved) { struct page *page = pages[(offset + copied) >> PAGE_SHIFT]; unsigned pg_offset = (offset + copied) & (PAGE_SIZE - 1); - unsigned pg_len = min_t(unsigned, len - copied, + unsigned pg_len = min_t(unsigned, reserved - copied, PAGE_SIZE - pg_offset); unsigned pg_copied = copy_page_from_iter_atomic(page, pg_offset, pg_len, iter); -- 2.30.2