Skip to content

Commit 9a46638

Browse files
jankarabrauner
authored andcommitted
fs: Handle multiply claimed blocks more gracefully with mmb
When a metadata block is referenced by multiple inodes and tracked by metadata bh infrastructure (which is forbidden and generally indicates filesystem corruption), it can happen that mmb_mark_buffer_dirty() is called for two different mmb structures in parallel. This can lead to a corruption of mmb linked list. Handle that situation gracefully (at least from mmb POV) by serializing on setting bh->b_mmb. Reported-by: Ruikai Peng <[email protected]> Signed-off-by: Jan Kara <[email protected]> Link: https://patch.msgid.link/[email protected] Signed-off-by: Christian Brauner <[email protected]>
1 parent 43eb354 commit 9a46638

1 file changed

Lines changed: 8 additions & 1 deletion

File tree

fs/buffer.c

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -719,8 +719,15 @@ void mmb_mark_buffer_dirty(struct buffer_head *bh,
719719
mark_buffer_dirty(bh);
720720
if (!bh->b_mmb) {
721721
spin_lock(&mmb->lock);
722+
/*
723+
* For a corrupted filesystem with multiply claimed blocks this
724+
* can fail. Avoid corrupting the linked list in that case.
725+
*/
726+
if (cmpxchg(&bh->b_mmb, NULL, mmb) != NULL) {
727+
spin_unlock(&mmb->lock);
728+
return;
729+
}
722730
list_move_tail(&bh->b_assoc_buffers, &mmb->list);
723-
bh->b_mmb = mmb;
724731
spin_unlock(&mmb->lock);
725732
}
726733
}

0 commit comments

Comments
 (0)