On Thu, Aug 28, 2025 at 1:16 PM Max Kellermann <max.kellermann@xxxxxxxxx> wrote: > > The function move_dirty_folio_in_page_array() was created by commit > ce80b76dd327 ("ceph: introduce ceph_process_folio_batch() method") by > moving code from ceph_writepages_start() to this function. > > This new function is supposed to return an error code which is checked > by the caller (now ceph_process_folio_batch()), and on error, the > caller invokes redirty_page_for_writepage() and then breaks from the > loop. > > However, the refactoring commit has gone wrong, and it by accident, it > always returns 0 (= success) because it first NULLs the pointer and > then returns PTR_ERR(NULL) which is always 0. This means errors are > silently ignored, leaving NULL entries in the page array, which may > later crash the kernel. > > The simple solution is to call PTR_ERR() before clearing the pointer. > > Fixes: ce80b76dd327 ("ceph: introduce ceph_process_folio_batch() method") > Link: https://lore.kernel.org/ceph-devel/aK4v548CId5GIKG1@xxxxxxxxxxxxxx/ > Cc: stable@xxxxxxxxxxxxxxx > Signed-off-by: Max Kellermann <max.kellermann@xxxxxxxxx> > --- > fs/ceph/addr.c | 6 ++++-- > 1 file changed, 4 insertions(+), 2 deletions(-) > > diff --git a/fs/ceph/addr.c b/fs/ceph/addr.c > index 8b202d789e93..e3e0d477f3f7 100644 > --- a/fs/ceph/addr.c > +++ b/fs/ceph/addr.c > @@ -1264,7 +1264,9 @@ static inline int move_dirty_folio_in_page_array(struct address_space *mapping, > 0, > gfp_flags); > if (IS_ERR(pages[index])) { > - if (PTR_ERR(pages[index]) == -EINVAL) { > + int err = PTR_ERR(pages[index]); > + > + if (err == -EINVAL) { > pr_err_client(cl, "inode->i_blkbits=%hhu\n", > inode->i_blkbits); > } > @@ -1273,7 +1275,7 @@ static inline int move_dirty_folio_in_page_array(struct address_space *mapping, > BUG_ON(ceph_wbc->locked_pages == 0); > > pages[index] = NULL; > - return PTR_ERR(pages[index]); > + return err; > } > } else { > pages[index] = &folio->page; > -- > 2.47.2 > Queued up for 6.17-rc6. Thanks, Ilya