ext4l: Add journal_head detection in bh_cache_clear

When debugging journal-cleanup issues, stale journal_head attachments on
buffer_heads can cause crashes on subsequent mounts.

Add detection logic in bh_cache_clear() to warn when a buffer_head still
has a journal_head attached. This indicates the journal was not properly
destroyed before unmount. Clear the JBD flag and pointer to prevent
issues with subsequent mounts.

Co-developed-by: Claude Opus 4.5 <noreply@anthropic.com>
Signed-off-by: Simon Glass <simon.glass@canonical.com>
This commit is contained in:
Simon Glass
2025-12-29 14:27:26 -07:00
parent e63fc511c3
commit 014f082f05

View File

@@ -222,6 +222,29 @@ static void bh_cache_insert(struct buffer_head *bh)
*
* Called on unmount to free all cached buffers.
*/
/**
* bh_clear_stale_jbd() - Clear stale journal_head from buffer_head
* @bh: buffer_head to check
*
* Check if the buffer still has journal_head attached. This should not happen
* if the journal was properly destroyed, but warn if it does to help debugging.
* Clear the JBD flag and b_private to prevent issues with subsequent mounts.
*/
static void bh_clear_stale_jbd(struct buffer_head *bh)
{
if (buffer_jbd(bh)) {
log_err("bh %p block %llu still has JBD (b_private %p)\n",
bh, (unsigned long long)bh->b_blocknr, bh->b_private);
/*
* Clear the JBD flag and b_private to prevent issues.
* The journal_head itself will be freed when the
* journal_head cache is destroyed.
*/
clear_buffer_jbd(bh);
bh->b_private = NULL;
}
}
void bh_cache_clear(void)
{
int i;
@@ -231,9 +254,12 @@ void bh_cache_clear(void)
for (entry = bh_cache[i]; entry; entry = next) {
next = entry->next;
if (entry->bh) {
struct buffer_head *bh = entry->bh;
bh_clear_stale_jbd(bh);
/* Release the cache's reference */
if (atomic_dec_and_test(&entry->bh->b_count))
free_buffer_head(entry->bh);
if (atomic_dec_and_test(&bh->b_count))
free_buffer_head(bh);
}
free(entry);
}