Unverified Commit 9a466382 authored by Jan Kara's avatar Jan Kara Committed by Christian Brauner
Browse files

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: default avatarRuikai Peng <ruikai@pwno.io>
Signed-off-by: default avatarJan Kara <jack@suse.cz>
Link: https://patch.msgid.link/20260423090311.10955-2-jack@suse.cz


Signed-off-by: default avatarChristian Brauner <brauner@kernel.org>
parent 43eb354e
Loading
Loading
Loading
Loading
+8 −1
Original line number Diff line number Diff line
@@ -719,8 +719,15 @@ void mmb_mark_buffer_dirty(struct buffer_head *bh,
	mark_buffer_dirty(bh);
	if (!bh->b_mmb) {
		spin_lock(&mmb->lock);
		/*
		 * For a corrupted filesystem with multiply claimed blocks this
		 * can fail. Avoid corrupting the linked list in that case.
		 */
		if (cmpxchg(&bh->b_mmb, NULL, mmb) != NULL) {
			spin_unlock(&mmb->lock);
			return;
		}
		list_move_tail(&bh->b_assoc_buffers, &mmb->list);
		bh->b_mmb = mmb;
		spin_unlock(&mmb->lock);
	}
}