[Concept,02/15] ext4l: Add journal_head detection in bh_cache_clear
Commit Message
From: Simon Glass <simon.glass@canonical.com>
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>
---
fs/ext4l/support.c | 30 ++++++++++++++++++++++++++++--
1 file changed, 28 insertions(+), 2 deletions(-)
@@ -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);
}