mirror of
https://github.com/torvalds/linux.git
synced 2026-11-07 06:17:02 +01:00
dm-snapshot: make the chunk list sorted by the chunk number
Commit8581b19eb2("dm-snapshot: fix 'scheduling while atomic' on real-time kernels") replaced hlist_bl_for_each_entry with hlist_for_each_entry, but the two iteration macros differ after the loop ends: hlist_bl_for_each_entry leaves "e" pointing at the last element, while hlist_for_each_entry() sets it to NULL. The result is that the list is no longer sorted by chunk number as it was intended to be. This bug doesn't cause data corruption because dm_lookup_exception walks the full list. Restore the invariant by tracking the list tail in the "prev" variable and appending after it with hlist_add_behind. Signed-off-by: Mikulas Patocka <mpatocka@redhat.com> Fixes:8581b19eb2("dm-snapshot: fix 'scheduling while atomic' on real-time kernels") Assisted-by: Claude:claude-opus-5
This commit is contained in:
parent
829c4d2114
commit
bbd6f974d0
|
|
@ -766,7 +766,7 @@ static void dm_insert_exception(struct dm_exception_table *eh,
|
|||
struct dm_exception *new_e)
|
||||
{
|
||||
struct hlist_head *l;
|
||||
struct dm_exception *e = NULL;
|
||||
struct dm_exception *e = NULL, *prev = NULL;
|
||||
|
||||
l = &eh->table[exception_hash(eh, new_e->old_chunk)].head;
|
||||
|
||||
|
|
@ -798,21 +798,23 @@ static void dm_insert_exception(struct dm_exception_table *eh,
|
|||
|
||||
if (new_e->old_chunk < e->old_chunk)
|
||||
break;
|
||||
|
||||
prev = e;
|
||||
}
|
||||
|
||||
out:
|
||||
if (!e) {
|
||||
if (e && new_e->old_chunk < e->old_chunk) {
|
||||
/* Add before an existing exception */
|
||||
hlist_add_before(&new_e->hash_list, &e->hash_list);
|
||||
} else if (prev) {
|
||||
/* Add to l's tail: prev is the last exception in this slot */
|
||||
hlist_add_behind(&new_e->hash_list, &prev->hash_list);
|
||||
} else {
|
||||
/*
|
||||
* Either the table doesn't support consecutive chunks or slot
|
||||
* l is empty.
|
||||
*/
|
||||
hlist_add_head(&new_e->hash_list, l);
|
||||
} else if (new_e->old_chunk < e->old_chunk) {
|
||||
/* Add before an existing exception */
|
||||
hlist_add_before(&new_e->hash_list, &e->hash_list);
|
||||
} else {
|
||||
/* Add to l's tail: e is the last exception in this slot */
|
||||
hlist_add_behind(&new_e->hash_list, &e->hash_list);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user