From 2bc09cb0e9e44c7e622b956332ebfb9b638fd5f7 Mon Sep 17 00:00:00 2001 From: Mike Marshall Date: Mon, 7 Sep 2026 12:02:40 -0400 Subject: [PATCH] orangefs: don't continue on to gpf if client dies on write. I got a message from Farhad Alemi (farhad.alemi@berkeley.edu) showing that this can happen: Oops: general protection fault, probably for non-canonical address 0xdffffc0000000002: 0000 [#1] SMP KASAN NOPTI KASAN: null-ptr-deref in range [0x0000000000000010-0x0000000000000017] RIP: 0010:orangefs_writepages_callback fs/orangefs/inode.c:144 [inline] RIP: 0010:orangefs_writepages+0x642/0xc60 fs/orangefs/inode.c:205 Call Trace: orangefs_writepages+0x642/0xc60 fs/orangefs/inode.c:205 do_writepages+0x328/0x550 mm/page-writeback.c:2571 filemap_write_and_wait_range+0x332/0x3f0 mm/filemap.c:685 orangefs_flush+0x44/0x60 fs/orangefs/file.c:566 filp_flush+0xbd/0x190 fs/open.c:1467 filp_close+0x1d/0x40 fs/open.c:1480 close_files fs/file.c:494 [inline] put_files_struct+0x1b6/0x340 fs/file.c:509 do_exit+0x6a8/0x2360 kernel/exit.c:971 With the help of Grok I created a reproducer program that causes a gpf on the same line: "ow->folios[ow->nfolios++] = folio;" in orangefs_writepages_callback. The reproducer program flows into this new code after this patch. Signed-off-by: Mike Marshall --- fs/orangefs/inode.c | 21 ++++++++++++++++++++- 1 file changed, 20 insertions(+), 1 deletion(-) diff --git a/fs/orangefs/inode.c b/fs/orangefs/inode.c index cd3273c88e03..c088a02e8215 100644 --- a/fs/orangefs/inode.c +++ b/fs/orangefs/inode.c @@ -181,8 +181,27 @@ static int orangefs_writepages(struct address_space *mapping, { struct orangefs_writepages *ow; struct blk_plug plug; - int error; + int error = 0; struct folio *folio = NULL; + int maxpages; + + maxpages = orangefs_bufmap_size_query() / PAGE_SIZE; + if (maxpages < 1) { + /* + * Probably the client is dead and there's no bufmap. + * Walk writeback_iter anyway so each dirty folio is unlocked + * and writeback is ended. wait_for_direct_io will fail; the + * data is not written. + */ + gossip_err("%s: maxpages < 1. \n", __func__); + while ((folio = writeback_iter(mapping, wbc, folio, &error))) { + error = orangefs_writepage_locked(folio, wbc); + mapping_set_error(mapping, error); + folio_unlock(folio); + folio_end_writeback(folio); + } + return error; + } ow = kzalloc_obj(struct orangefs_writepages); if (!ow)