--- /dev/null
+From f83913f8c5b882a312e72b7669762f8a5c9385e4 Mon Sep 17 00:00:00 2001
+From: Ryusuke Konishi <konishi.ryusuke@gmail.com>
+Date: Sat, 5 Aug 2023 22:20:38 +0900
+Subject: nilfs2: fix general protection fault in nilfs_lookup_dirty_data_buffers()
+
+From: Ryusuke Konishi <konishi.ryusuke@gmail.com>
+
+commit f83913f8c5b882a312e72b7669762f8a5c9385e4 upstream.
+
+A syzbot stress test reported that create_empty_buffers() called from
+nilfs_lookup_dirty_data_buffers() can cause a general protection fault.
+
+Analysis using its reproducer revealed that the back reference "mapping"
+from a page/folio has been changed to NULL after dirty page/folio gang
+lookup in nilfs_lookup_dirty_data_buffers().
+
+Fix this issue by excluding pages/folios from being collected if, after
+acquiring a lock on each page/folio, its back reference "mapping" differs
+from the pointer to the address space struct that held the page/folio.
+
+Link: https://lkml.kernel.org/r/20230805132038.6435-1-konishi.ryusuke@gmail.com
+Signed-off-by: Ryusuke Konishi <konishi.ryusuke@gmail.com>
+Reported-by: syzbot+0ad741797f4565e7e2d2@syzkaller.appspotmail.com
+Closes: https://lkml.kernel.org/r/0000000000002930a705fc32b231@google.com
+Tested-by: Ryusuke Konishi <konishi.ryusuke@gmail.com>
+Cc: <stable@vger.kernel.org>
+Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
+Signed-off-by: Ryusuke Konishi <konishi.ryusuke@gmail.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+fs/nilfs2/segment.c | 5 +++++
+ fs/nilfs2/segment.c | 5 +++++
+ 1 file changed, 5 insertions(+)
+
+--- a/fs/nilfs2/segment.c
++++ b/fs/nilfs2/segment.c
+@@ -730,6 +730,11 @@ static size_t nilfs_lookup_dirty_data_bu
+ struct page *page = pvec.pages[i];
+
+ lock_page(page);
++ if (unlikely(page->mapping != mapping)) {
++ /* Exclude pages removed from the address space */
++ unlock_page(page);
++ continue;
++ }
+ if (!page_has_buffers(page))
+ create_empty_buffers(page, i_blocksize(inode), 0);
+ unlock_page(page);
--- /dev/null
+From cdaac8e7e5a059f9b5e816cda257f08d0abffacd Mon Sep 17 00:00:00 2001
+From: Ryusuke Konishi <konishi.ryusuke@gmail.com>
+Date: Fri, 18 Aug 2023 22:18:04 +0900
+Subject: nilfs2: fix WARNING in mark_buffer_dirty due to discarded buffer reuse
+
+From: Ryusuke Konishi <konishi.ryusuke@gmail.com>
+
+commit cdaac8e7e5a059f9b5e816cda257f08d0abffacd upstream.
+
+A syzbot stress test using a corrupted disk image reported that
+mark_buffer_dirty() called from __nilfs_mark_inode_dirty() or
+nilfs_palloc_commit_alloc_entry() may output a kernel warning, and can
+panic if the kernel is booted with panic_on_warn.
+
+This is because nilfs2 keeps buffer pointers in local structures for some
+metadata and reuses them, but such buffers may be forcibly discarded by
+nilfs_clear_dirty_page() in some critical situations.
+
+This issue is reported to appear after commit 28a65b49eb53 ("nilfs2: do
+not write dirty data after degenerating to read-only"), but the issue has
+potentially existed before.
+
+Fix this issue by checking the uptodate flag when attempting to reuse an
+internally held buffer, and reloading the metadata instead of reusing the
+buffer if the flag was lost.
+
+Link: https://lkml.kernel.org/r/20230818131804.7758-1-konishi.ryusuke@gmail.com
+Signed-off-by: Ryusuke Konishi <konishi.ryusuke@gmail.com>
+Reported-by: syzbot+cdfcae656bac88ba0e2d@syzkaller.appspotmail.com
+Closes: https://lkml.kernel.org/r/0000000000003da75f05fdeffd12@google.com
+Fixes: 8c26c4e2694a ("nilfs2: fix issue with flush kernel thread after remount in RO mode because of driver's internal error or metadata corruption")
+Tested-by: Ryusuke Konishi <konishi.ryusuke@gmail.com>
+Cc: <stable@vger.kernel.org> # 3.10+
+Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ fs/nilfs2/alloc.c | 3 ++-
+ fs/nilfs2/inode.c | 7 +++++--
+ 2 files changed, 7 insertions(+), 3 deletions(-)
+
+--- a/fs/nilfs2/alloc.c
++++ b/fs/nilfs2/alloc.c
+@@ -205,7 +205,8 @@ static int nilfs_palloc_get_block(struct
+ int ret;
+
+ spin_lock(lock);
+- if (prev->bh && blkoff == prev->blkoff) {
++ if (prev->bh && blkoff == prev->blkoff &&
++ likely(buffer_uptodate(prev->bh))) {
+ get_bh(prev->bh);
+ *bhp = prev->bh;
+ spin_unlock(lock);
+--- a/fs/nilfs2/inode.c
++++ b/fs/nilfs2/inode.c
+@@ -1036,7 +1036,7 @@ int nilfs_load_inode_block(struct inode
+ int err;
+
+ spin_lock(&nilfs->ns_inode_lock);
+- if (ii->i_bh == NULL) {
++ if (ii->i_bh == NULL || unlikely(!buffer_uptodate(ii->i_bh))) {
+ spin_unlock(&nilfs->ns_inode_lock);
+ err = nilfs_ifile_get_inode_block(ii->i_root->ifile,
+ inode->i_ino, pbh);
+@@ -1045,7 +1045,10 @@ int nilfs_load_inode_block(struct inode
+ spin_lock(&nilfs->ns_inode_lock);
+ if (ii->i_bh == NULL)
+ ii->i_bh = *pbh;
+- else {
++ else if (unlikely(!buffer_uptodate(ii->i_bh))) {
++ __brelse(ii->i_bh);
++ ii->i_bh = *pbh;
++ } else {
+ brelse(*pbh);
+ *pbh = ii->i_bh;
+ }