From 00ea81459c279f14a7b344320a71c94f60f88929 Mon Sep 17 00:00:00 2001 From: Jan Kara Date: Thu, 2 Jun 2005 14:02:00 -0700 Subject: [PATCH] ext3: fix log_do_checkpoint() assertion failure Fix possible false assertion failure in log_do_checkpoint(). We might fail to detect that we actually made a progress when cleaning up the checkpoint lists if we don't retry after writing something to disk. The patch was confirmed to fix observed assertion failures for several users. When we flushed some buffers we need to retry scanning the list. Otherwise we can fail to detect our progress. Signed-off-by: Jan Kara Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- fs/jbd/checkpoint.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'fs/jbd/checkpoint.c') diff --git a/fs/jbd/checkpoint.c b/fs/jbd/checkpoint.c index 98d830401c56..58133ab9457e 100644 --- a/fs/jbd/checkpoint.c +++ b/fs/jbd/checkpoint.c @@ -339,8 +339,10 @@ int log_do_checkpoint(journal_t *journal) } } while (jh != last_jh && !retry); - if (batch_count) + if (batch_count) { __flush_batch(journal, bhs, &batch_count); + retry = 1; + } /* * If someone cleaned up this transaction while we slept, we're -- cgit v1.2.3 From 7e3b11a9be6ac94bf4af81757b6a10e7e65b846f Mon Sep 17 00:00:00 2001 From: Jan Kara Date: Thu, 2 Jun 2005 14:02:01 -0700 Subject: [PATCH] ext3: fix list scanning in __cleanup_transaction Fix a bug in list scanning that can cause us to skip the last buffer on the checkpoint list (and hence fail to do any progress under some rather unfavorable conditions). The problem is we first do jh=next_jh and then test } while (jh!=last_jh); Hence we skip the last buffer on the list (if it was not the only buffer on the list). As we already do jh=next_jh; in the beginning of the loop we are safe to just remove the assignment in the end. It can happen that 'jh' will be freed at the point we test jh != last_jh but that does not matter as we never *dereference* the pointer. Signed-off-by: Jan Kara Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- fs/jbd/checkpoint.c | 1 - 1 file changed, 1 deletion(-) (limited to 'fs/jbd/checkpoint.c') diff --git a/fs/jbd/checkpoint.c b/fs/jbd/checkpoint.c index 58133ab9457e..5a97e346bd95 100644 --- a/fs/jbd/checkpoint.c +++ b/fs/jbd/checkpoint.c @@ -188,7 +188,6 @@ static int __cleanup_transaction(journal_t *journal, transaction_t *transaction) } else { jbd_unlock_bh_state(bh); } - jh = next_jh; } while (jh != last_jh); return ret; -- cgit v1.2.3