diff --git a/fs/bcachefs/fs-io-pagecache.c b/fs/bcachefs/fs-io-pagecache.c
index a9cc5cad9cc9..a4efa1b76035 100644
--- a/fs/bcachefs/fs-io-pagecache.c
+++ b/fs/bcachefs/fs-io-pagecache.c
@@ -611,7 +611,8 @@ vm_fault_t bch2_page_mkwrite(struct vm_fault *vmf)
 
 	bch2_folio_reservation_init(c, inode, &res);
 
-	sb_start_pagefault(inode->v.i_sb);
+	if (sb_start_pagefault(inode->v.i_sb) < 0)
+		return VM_FAULT_SIGBUS;
 	file_update_time(file);
 
 	/*
diff --git a/fs/btrfs/file.c b/fs/btrfs/file.c
index 21381de906f6..481d355c66ee 100644
--- a/fs/btrfs/file.c
+++ b/fs/btrfs/file.c
@@ -1900,7 +1900,8 @@ static vm_fault_t btrfs_page_mkwrite(struct vm_fault *vmf)
 
 	reserved_space = PAGE_SIZE;
 
-	sb_start_pagefault(inode->i_sb);
+	if (sb_start_pagefault(inode->i_sb) < 0)
+		return VM_FAULT_SIGBUS;
 	page_start = page_offset(page);
 	page_end = page_start + PAGE_SIZE - 1;
 	end = page_end;
diff --git a/fs/ceph/addr.c b/fs/ceph/addr.c
index 8c16bc5250ef..60ddddce4ec1 100644
--- a/fs/ceph/addr.c
+++ b/fs/ceph/addr.c
@@ -1686,7 +1686,9 @@ static vm_fault_t ceph_page_mkwrite(struct vm_fault *vmf)
 	if (!prealloc_cf)
 		return VM_FAULT_OOM;
 
-	sb_start_pagefault(inode->i_sb);
+	err = sb_start_pagefault(inode->i_sb);
+	if (err)
+		goto out_free;
 	ceph_block_sigs(&oldset);
 
 	if (off + thp_size(page) <= size)
@@ -1704,7 +1706,7 @@ static vm_fault_t ceph_page_mkwrite(struct vm_fault *vmf)
 	got = 0;
 	err = ceph_get_caps(vma->vm_file, CEPH_CAP_FILE_WR, want, off + len, &got);
 	if (err < 0)
-		goto out_free;
+		goto out_sigs;
 
 	doutc(cl, "%llx.%llx %llu~%zd got cap refs on %s\n", ceph_vinop(inode),
 	      off, len, ceph_cap_string(got));
@@ -1758,9 +1760,10 @@ static vm_fault_t ceph_page_mkwrite(struct vm_fault *vmf)
 	doutc(cl, "%llx.%llx %llu~%zd dropping cap refs on %s ret %x\n",
 	      ceph_vinop(inode), off, len, ceph_cap_string(got), ret);
 	ceph_put_cap_refs_async(ci, got);
-out_free:
+out_sigs:
 	ceph_restore_sigs(&oldset);
 	sb_end_pagefault(inode->i_sb);
+out_free:
 	ceph_free_cap_flush(prealloc_cf);
 	if (err < 0)
 		ret = vmf_error(err);
diff --git a/fs/ext2/file.c b/fs/ext2/file.c
index 10b061ac5bc0..b57197007b28 100644
--- a/fs/ext2/file.c
+++ b/fs/ext2/file.c
@@ -98,7 +98,8 @@ static vm_fault_t ext2_dax_fault(struct vm_fault *vmf)
 		(vmf->vma->vm_flags & VM_SHARED);
 
 	if (write) {
-		sb_start_pagefault(inode->i_sb);
+		if (sb_start_pagefault(inode->i_sb) < 0)
+			return VM_FAULT_SIGBUS;
 		file_update_time(vmf->vma->vm_file);
 	}
 	filemap_invalidate_lock_shared(inode->i_mapping);
diff --git a/fs/ext4/file.c b/fs/ext4/file.c
index c89e434db6b7..37623d4624c0 100644
--- a/fs/ext4/file.c
+++ b/fs/ext4/file.c
@@ -725,7 +725,8 @@ static vm_fault_t ext4_dax_huge_fault(struct vm_fault *vmf, unsigned int order)
 	pfn_t pfn;
 
 	if (write) {
-		sb_start_pagefault(sb);
+		if (sb_start_pagefault(sb) < 0)
+			return VM_FAULT_SIGBUS;
 		file_update_time(vmf->vma->vm_file);
 		filemap_invalidate_lock_shared(mapping);
 retry:
diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c
index 941c1c0d5c6e..195fcbb5c083 100644
--- a/fs/ext4/inode.c
+++ b/fs/ext4/inode.c
@@ -6128,7 +6128,8 @@ vm_fault_t ext4_page_mkwrite(struct vm_fault *vmf)
 	if (unlikely(IS_IMMUTABLE(inode)))
 		return VM_FAULT_SIGBUS;
 
-	sb_start_pagefault(inode->i_sb);
+	if (unlikely(sb_start_pagefault(inode->i_sb) < 0))
+		return VM_FAULT_SIGBUS;
 	file_update_time(vma->vm_file);
 
 	filemap_invalidate_lock_shared(mapping);
diff --git a/fs/f2fs/file.c b/fs/f2fs/file.c
index 168f08507004..67ee66ff75a7 100644
--- a/fs/f2fs/file.c
+++ b/fs/f2fs/file.c
@@ -100,7 +100,9 @@ static vm_fault_t f2fs_vm_page_mkwrite(struct vm_fault *vmf)
 	if (need_alloc)
 		f2fs_balance_fs(sbi, true);
 
-	sb_start_pagefault(inode->i_sb);
+	err = sb_start_pagefault(inode->i_sb);
+	if (err)
+		goto out;
 
 	f2fs_bug_on(sbi, f2fs_has_inline_data(inode));
 
diff --git a/fs/fuse/dax.c b/fs/fuse/dax.c
index 12ef91d170bb..d42d0aaa1bd9 100644
--- a/fs/fuse/dax.c
+++ b/fs/fuse/dax.c
@@ -797,7 +797,8 @@ static vm_fault_t __fuse_dax_fault(struct vm_fault *vmf, unsigned int order,
 	bool retry = false;
 
 	if (write)
-		sb_start_pagefault(sb);
+		if (sb_start_pagefault(sb) < 0)
+			return VM_FAULT_SIGBUS;
 retry:
 	if (retry && !(fcd->nr_free_ranges > 0))
 		wait_event(fcd->range_waitq, (fcd->nr_free_ranges > 0));
diff --git a/fs/gfs2/file.c b/fs/gfs2/file.c
index 08982937b5df..774203da5262 100644
--- a/fs/gfs2/file.c
+++ b/fs/gfs2/file.c
@@ -427,7 +427,8 @@ static vm_fault_t gfs2_page_mkwrite(struct vm_fault *vmf)
 	loff_t size;
 	int err;
 
-	sb_start_pagefault(inode->i_sb);
+	if (sb_start_pagefault(inode->i_sb) < 0)
+		return VM_FAULT_SIGBUS;
 
 	gfs2_holder_init(ip->i_gl, LM_ST_EXCLUSIVE, 0, &gh);
 	err = gfs2_glock_nq(&gh);
diff --git a/fs/netfs/buffered_write.c b/fs/netfs/buffered_write.c
index 4726c315453c..e46fcd387be6 100644
--- a/fs/netfs/buffered_write.c
+++ b/fs/netfs/buffered_write.c
@@ -531,7 +531,8 @@ vm_fault_t netfs_page_mkwrite(struct vm_fault *vmf, struct netfs_group *netfs_gr
 
 	_enter("%lx", folio->index);
 
-	sb_start_pagefault(inode->i_sb);
+	if (sb_start_pagefault(inode->i_sb) < 0)
+		return VM_FAULT_SIGBUS;
 
 	if (folio_lock_killable(folio) < 0)
 		goto out;
diff --git a/fs/nfs/file.c b/fs/nfs/file.c
index 61a8cdb9f1e1..ae0791c67ab8 100644
--- a/fs/nfs/file.c
+++ b/fs/nfs/file.c
@@ -593,7 +593,8 @@ static vm_fault_t nfs_vm_page_mkwrite(struct vm_fault *vmf)
 		 filp, filp->f_mapping->host->i_ino,
 		 (long long)folio_pos(folio));
 
-	sb_start_pagefault(inode->i_sb);
+	if (sb_start_pagefault(inode->i_sb) < 0)
+		return VM_FAULT_SIGBUS;
 
 	/* make sure the cache has finished storing the page */
 	if (folio_test_private_2(folio) && /* [DEPRECATED] */
diff --git a/fs/nilfs2/file.c b/fs/nilfs2/file.c
index 0e3fc5ba33c7..6e80377250d1 100644
--- a/fs/nilfs2/file.c
+++ b/fs/nilfs2/file.c
@@ -54,7 +54,8 @@ static vm_fault_t nilfs_page_mkwrite(struct vm_fault *vmf)
 	if (unlikely(nilfs_near_disk_full(inode->i_sb->s_fs_info)))
 		return VM_FAULT_SIGBUS; /* -ENOSPC */
 
-	sb_start_pagefault(inode->i_sb);
+	if (sb_start_pagefault(inode->i_sb) < 0)
+		return VM_FAULT_SIGBUS;
 	folio_lock(folio);
 	if (folio->mapping != inode->i_mapping ||
 	    folio_pos(folio) >= i_size_read(inode) ||
diff --git a/fs/ocfs2/mmap.c b/fs/ocfs2/mmap.c
index 1834f26522ed..a56465a3a515 100644
--- a/fs/ocfs2/mmap.c
+++ b/fs/ocfs2/mmap.c
@@ -119,7 +119,8 @@ static vm_fault_t ocfs2_page_mkwrite(struct vm_fault *vmf)
 	int err;
 	vm_fault_t ret;
 
-	sb_start_pagefault(inode->i_sb);
+	if (sb_start_pagefault(inode->i_sb) < 0)
+		return VM_FAULT_SIGBUS;
 	ocfs2_block_signals(&oldset);
 
 	/*
diff --git a/fs/orangefs/inode.c b/fs/orangefs/inode.c
index fdb9b65db1de..170ef9456ff1 100644
--- a/fs/orangefs/inode.c
+++ b/fs/orangefs/inode.c
@@ -632,7 +632,8 @@ vm_fault_t orangefs_page_mkwrite(struct vm_fault *vmf)
 	vm_fault_t ret;
 	struct orangefs_write_range *wr;
 
-	sb_start_pagefault(inode->i_sb);
+	if (sb_start_pagefault(inode->i_sb) < 0)
+		return VM_FAULT_SIGBUS;
 
 	if (wait_on_bit(bitlock, 1, TASK_KILLABLE)) {
 		ret = VM_FAULT_RETRY;
diff --git a/fs/udf/file.c b/fs/udf/file.c
index 3a4179de316b..d97ba972f1f3 100644
--- a/fs/udf/file.c
+++ b/fs/udf/file.c
@@ -45,7 +45,8 @@ static vm_fault_t udf_page_mkwrite(struct vm_fault *vmf)
 	vm_fault_t ret = VM_FAULT_LOCKED;
 	int err;
 
-	sb_start_pagefault(inode->i_sb);
+	if (sb_start_pagefault(inode->i_sb) < 0)
+		return VM_FAULT_SIGBUS;
 	file_update_time(vma->vm_file);
 	filemap_invalidate_lock_shared(mapping);
 	folio_lock(folio);
diff --git a/fs/xfs/xfs_file.c b/fs/xfs/xfs_file.c
index 4cdc54dc9686..7e2c9bd70bc2 100644
--- a/fs/xfs/xfs_file.c
+++ b/fs/xfs/xfs_file.c
@@ -1283,7 +1283,8 @@ xfs_write_fault(
 	unsigned int		lock_mode = XFS_MMAPLOCK_SHARED;
 	vm_fault_t		ret;
 
-	sb_start_pagefault(inode->i_sb);
+	if (sb_start_pagefault(inode->i_sb) < 0)
+		return VM_FAULT_SIGBUS;
 	file_update_time(vmf->vma->vm_file);
 
 	/*
diff --git a/fs/zonefs/file.c b/fs/zonefs/file.c
index 3b103715acc9..0b100d48056a 100644
--- a/fs/zonefs/file.c
+++ b/fs/zonefs/file.c
@@ -294,7 +294,8 @@ static vm_fault_t zonefs_filemap_page_mkwrite(struct vm_fault *vmf)
 	if (zonefs_inode_is_seq(inode))
 		return VM_FAULT_NOPAGE;
 
-	sb_start_pagefault(inode->i_sb);
+	if (sb_start_pagefault(inode->i_sb) < 0)
+		return VM_FAULT_SIGBUS;
 	file_update_time(vmf->vma->vm_file);
 
 	/* Serialize against truncates */
diff --git a/include/linux/fs.h b/include/linux/fs.h
index 44ae86f46b12..a082777eac6a 100644
--- a/include/linux/fs.h
+++ b/include/linux/fs.h
@@ -1858,9 +1858,12 @@ static inline bool __must_check sb_start_write_trylock(struct super_block *sb)
  * mmap_lock
  *   -> sb_start_pagefault
  */
-static inline void sb_start_pagefault(struct super_block *sb)
+static inline int __must_check sb_start_pagefault(struct super_block *sb)
 {
+	if (sb_test_iflag(sb, SB_I_SHUTDOWN))
+		return -EROFS;
 	__sb_start_write(sb, SB_FREEZE_PAGEFAULT);
+	return 0;
 }
 
 /**
diff --git a/mm/filemap.c b/mm/filemap.c
index d62150418b91..97efc8a62c21 100644
--- a/mm/filemap.c
+++ b/mm/filemap.c
@@ -3672,7 +3672,8 @@ vm_fault_t filemap_page_mkwrite(struct vm_fault *vmf)
 	struct folio *folio = page_folio(vmf->page);
 	vm_fault_t ret = VM_FAULT_LOCKED;
 
-	sb_start_pagefault(mapping->host->i_sb);
+	if (sb_start_pagefault(mapping->host->i_sb) < 0)
+		return VM_FAULT_SIGBUS;
 	file_update_time(vmf->vma->vm_file);
 	folio_lock(folio);
 	if (folio->mapping != mapping) {
