diff --git a/ReleaseNotes.md b/ReleaseNotes.md index d5de4d96..99e0e0ec 100644 --- a/ReleaseNotes.md +++ b/ReleaseNotes.md @@ -14,6 +14,15 @@ v1.x unmounted. This can be used to change the mounts that will participate in quorum and the IP addresses they use. +* **Fix Rare Risk of Item Cache Corruption** +\ + Code review found a rare potential source of item cache corruption. + If this happened it would look as though deleted parts of the filesystem + returned, but only at the time they were deleted. Old deleted items are + not affected. This problem only affected the item cache, never + persistent storage. Unmounting and remounting would drop the bad item + cache and resync it with the correct persistent data. + --- v1.0 \ diff --git a/kmod/src/item.c b/kmod/src/item.c index 7151b380..05b04550 100644 --- a/kmod/src/item.c +++ b/kmod/src/item.c @@ -685,6 +685,12 @@ static void erase_page_items(struct cached_page *pg, * to the dirty list after the left page, and by adding items to the * tail of right's dirty list in key sort order. * + * The max_seq of the source page might be larger than all the items + * while protecting an erased item from being reclaimed while an older + * read is in flight. We don't know where it might be in the source + * page so we have to assume that it's in the key range being moved and + * update the destination page's max_seq accordingly. + * * The caller is responsible for page locking and managing the lru. */ static void move_page_items(struct super_block *sb, @@ -726,6 +732,9 @@ static void move_page_items(struct super_block *sb, erase_item(left, from); } + + if (left->max_seq > right->max_seq) + right->max_seq = left->max_seq; } enum page_intersection_type {