summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--fs/buffer.c10
1 files changed, 8 insertions, 2 deletions
diff --git a/fs/buffer.c b/fs/buffer.c
index 9af5f061a1f8..daaa6614a6d6 100644
--- a/fs/buffer.c
+++ b/fs/buffer.c
@@ -1123,12 +1123,18 @@ EXPORT_SYMBOL(mark_buffer_dirty);
void mark_buffer_write_io_error(struct buffer_head *bh)
{
+ struct mapping_metadata_bhs *mmb;
+
set_buffer_write_io_error(bh);
/* FIXME: do we need to set this in both places? */
if (bh->b_folio && bh->b_folio->mapping)
mapping_set_error(bh->b_folio->mapping, -EIO);
- if (bh->b_mmb)
- mapping_set_error(bh->b_mmb->mapping, -EIO);
+ /* Protect us from mmb & inode getting freed while we work on it */
+ rcu_read_lock();
+ mmb = READ_ONCE(bh->b_mmb);
+ if (mmb)
+ mapping_set_error(mmb->mapping, -EIO);
+ rcu_read_unlock();
}
EXPORT_SYMBOL(mark_buffer_write_io_error);