summaryrefslogtreecommitdiff
path: root/fs/bcachefs/fs-io.c
diff options
context:
space:
mode:
authorKent Overstreet <kent.overstreet@gmail.com>2021-11-11 21:02:03 +0300
committerKent Overstreet <kent.overstreet@linux.dev>2023-10-23 00:09:16 +0300
commitf74a5051b0e58a8f4fab26a2fc65b95ee17df7a0 (patch)
treecfa53595759cf43bf93a915e50330d10c5de2993 /fs/bcachefs/fs-io.c
parent770e821485e0021ea325f7aa2133fddb46ba0821 (diff)
downloadlinux-f74a5051b0e58a8f4fab26a2fc65b95ee17df7a0.tar.xz
bcachefs: Don't check for -ENOSPC in page writeback
If at all possible we'd prefer to not fail page writeback unless the filesystem has been shutdown; allowing errors in page writeback means things we'd like to assert about i_size consistency between the VFS and the btree go out the window. Signed-off-by: Kent Overstreet <kent.overstreet@gmail.com>
Diffstat (limited to 'fs/bcachefs/fs-io.c')
-rw-r--r--fs/bcachefs/fs-io.c29
1 files changed, 14 insertions, 15 deletions
diff --git a/fs/bcachefs/fs-io.c b/fs/bcachefs/fs-io.c
index 12b785c5005f..ac013bb99a43 100644
--- a/fs/bcachefs/fs-io.c
+++ b/fs/bcachefs/fs-io.c
@@ -1144,16 +1144,16 @@ static int __bch2_writepage(struct folio *folio,
do_io:
s = bch2_page_state_create(page, __GFP_NOFAIL);
- ret = bch2_get_page_disk_reservation(c, inode, page, true);
- if (ret) {
- SetPageError(page);
- mapping_set_error(page->mapping, ret);
- unlock_page(page);
- return 0;
- }
+ /*
+ * Things get really hairy with errors during writeback:
+ */
+ ret = bch2_get_page_disk_reservation(c, inode, page, false);
+ BUG_ON(ret);
/* Before unlocking the page, get copy of reservations: */
+ spin_lock(&s->lock);
orig = *s;
+ spin_unlock(&s->lock);
for (i = 0; i < PAGE_SECTORS; i++) {
if (s->s[i].state < SECTOR_DIRTY)
@@ -1186,7 +1186,7 @@ do_io:
offset = 0;
while (1) {
- unsigned sectors = 1, dirty_sectors = 0, reserved_sectors = 0;
+ unsigned sectors = 0, dirty_sectors = 0, reserved_sectors = 0;
u64 sector;
while (offset < PAGE_SECTORS &&
@@ -1196,16 +1196,15 @@ do_io:
if (offset == PAGE_SECTORS)
break;
- sector = ((u64) page->index << PAGE_SECTOR_SHIFT) + offset;
-
while (offset + sectors < PAGE_SECTORS &&
- orig.s[offset + sectors].state >= SECTOR_DIRTY)
+ orig.s[offset + sectors].state >= SECTOR_DIRTY) {
+ reserved_sectors += orig.s[offset + sectors].replicas_reserved;
+ dirty_sectors += orig.s[offset + sectors].state == SECTOR_DIRTY;
sectors++;
-
- for (i = offset; i < offset + sectors; i++) {
- reserved_sectors += orig.s[i].replicas_reserved;
- dirty_sectors += orig.s[i].state == SECTOR_DIRTY;
}
+ BUG_ON(!sectors);
+
+ sector = ((u64) page->index << PAGE_SECTOR_SHIFT) + offset;
if (w->io &&
(w->io->op.res.nr_replicas != nr_replicas_this_write ||