X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=fs%2Fjbd%2Fjournal.c;h=1cf23ff17c4a079ec19a0020986fd11e3c73deba;hb=9bf4aaab3e101692164d49b7ca357651eb691cb6;hp=a1e2a5d12cbe05f9da3af18e9c16e9cfdec5ccbb;hpb=db216c3d5e4c040e557a50f8f5d35d5c415e8c1c;p=linux-2.6.git diff --git a/fs/jbd/journal.c b/fs/jbd/journal.c index a1e2a5d12..1cf23ff17 100644 --- a/fs/jbd/journal.c +++ b/fs/jbd/journal.c @@ -73,6 +73,7 @@ EXPORT_SYMBOL(journal_ack_err); EXPORT_SYMBOL(journal_clear_err); EXPORT_SYMBOL(log_wait_commit); EXPORT_SYMBOL(journal_start_commit); +EXPORT_SYMBOL(journal_force_commit_nested); EXPORT_SYMBOL(journal_wipe); EXPORT_SYMBOL(journal_blocks_per_page); EXPORT_SYMBOL(journal_invalidatepage); @@ -464,6 +465,39 @@ int log_start_commit(journal_t *journal, tid_t tid) return ret; } +/* + * Force and wait upon a commit if the calling process is not within + * transaction. This is used for forcing out undo-protected data which contains + * bitmaps, when the fs is running out of space. + * + * We can only force the running transaction if we don't have an active handle; + * otherwise, we will deadlock. + * + * Returns true if a transaction was started. + */ +int journal_force_commit_nested(journal_t *journal) +{ + transaction_t *transaction = NULL; + tid_t tid; + + spin_lock(&journal->j_state_lock); + if (journal->j_running_transaction && !current->journal_info) { + transaction = journal->j_running_transaction; + __log_start_commit(journal, transaction->t_tid); + } else if (journal->j_committing_transaction) + transaction = journal->j_committing_transaction; + + if (!transaction) { + spin_unlock(&journal->j_state_lock); + return 0; /* Nothing to retry */ + } + + tid = transaction->t_tid; + spin_unlock(&journal->j_state_lock); + log_wait_commit(journal, tid); + return 1; +} + /* * Start a commit of the current running transaction (if any). Returns true * if a transaction was started, and fills its tid in at *ptid @@ -1583,7 +1617,7 @@ static void journal_destroy_journal_head_cache(void) { J_ASSERT(journal_head_cache != NULL); kmem_cache_destroy(journal_head_cache); - journal_head_cache = 0; + journal_head_cache = NULL; } /*