From: Zoltan Menyhart <Zoltan.Menyhart@bull.net>
To: Jan Kara <jack@suse.cz>
Cc: sct@redhat.com, linux-kernel@vger.kernel.org
Subject: Re: [PATCH] Change ll_rw_block() calls in JBD
Date: Wed, 24 May 2006 11:14:31 +0200 [thread overview]
Message-ID: <447423F7.5000002@bull.net> (raw)
In-Reply-To: <20060518134533.GA20159@atrey.karlin.mff.cuni.cz>
Yesterday I forgot a small "spin_unlock(&journal->j_list_lock);".
Thanks,
Zoltan
--- linux-2.6.16.16-save/fs/jbd/commit.c 2006-05-19 15:00:50.000000000 +0200
+++ linux-2.6.16.16/fs/jbd/commit.c 2006-05-24 10:43:32.000000000 +0200
@@ -161,6 +161,107 @@
}
/*
+ * Flush data from the "->t_sync_datalist" of the committing transaction.
+ */
+static void write_out_sync_data(journal_t *journal,
+ transaction_t *commit_transaction)
+{
+ struct journal_head *jh;
+ struct buffer_head *bh;
+ int err = 0;
+
+ /*
+ * Whenever we unlock the journal and sleep, things can get removed
+ * from "->t_sync_datalist" by "journal_dirty_data()", so we have
+ * to keep looping back to write_out_data until we *know* that the
+ * list is empty.
+ *
+ * Cleanup any flushed data buffers from the data list. Even in
+ * abort mode, we want to flush this out as soon as possible.
+ */
+write_out_data:
+ cond_resched();
+ spin_lock(&journal->j_list_lock);
+ while ((jh = commit_transaction->t_sync_datalist) != NULL){
+ bh = jh2bh(jh);
+ if (buffer_locked(bh)){ /* Unsafe */
+ BUFFER_TRACE(bh, "locked");
+ if (!inverted_lock(journal, bh)) /* jbd_lock_bh_state */
+ goto write_out_data;
+ /* "bh" may have been unlocked in the mean time */
+ __journal_file_buffer(jh, commit_transaction, BJ_Locked);
+ jbd_unlock_bh_state(bh);
+ } else {
+ /* "bh" may have become locked in the mean time */
+ if (buffer_dirty(bh)){ /* Unsafe */
+ if (test_set_buffer_locked(bh)){
+ BUFFER_TRACE(bh, "locked");
+ /* Put it on the BJ_Locked list */
+ continue;
+ }
+ if (test_clear_buffer_dirty(bh)){
+ BUFFER_TRACE(bh, "start journal wr");
+ spin_unlock(&journal->j_list_lock);
+ get_bh(bh);
+ bh->b_end_io = end_buffer_write_sync;
+ submit_bh(WRITE, bh);
+ /* Put it on the BJ_Locked list */
+ goto write_out_data;
+ }
+ unlock_buffer(bh);
+ } else {
+ /* "bh" may have become dirty in the mean time */
+ /* Just do nothing for this transaction */
+ }
+ BUFFER_TRACE(bh, "writeout complete: unfile");
+ if (!inverted_lock(journal, bh)) /* jbd_lock_bh_state */
+ goto write_out_data;
+ __journal_unfile_buffer(jh);
+ jbd_unlock_bh_state(bh);
+ journal_remove_journal_head(bh);
+ put_bh(bh);
+ }
+ if (lock_need_resched(&journal->j_list_lock)){
+ spin_unlock(&journal->j_list_lock);
+ goto write_out_data;
+ }
+ }
+ /*
+ * Wait for all previously submitted IO to complete.
+ */
+ while (commit_transaction->t_locked_list) {
+ jh = commit_transaction->t_locked_list->b_tprev;
+ bh = jh2bh(jh);
+ get_bh(bh);
+ if (buffer_locked(bh)) {
+ spin_unlock(&journal->j_list_lock);
+ wait_on_buffer(bh);
+ if (unlikely(!buffer_uptodate(bh)))
+ err = -EIO;
+ spin_lock(&journal->j_list_lock);
+ }
+ if (!inverted_lock(journal, bh)) {
+ put_bh(bh);
+ spin_lock(&journal->j_list_lock);
+ continue;
+ }
+ if (buffer_jbd(bh) && jh->b_jlist == BJ_Locked) {
+ __journal_unfile_buffer(jh);
+ jbd_unlock_bh_state(bh);
+ journal_remove_journal_head(bh);
+ put_bh(bh);
+ } else {
+ jbd_unlock_bh_state(bh);
+ }
+ put_bh(bh);
+ cond_resched_lock(&journal->j_list_lock);
+ }
+ spin_unlock(&journal->j_list_lock);
+ if (err)
+ __journal_abort_hard(journal);
+}
+
+/*
* journal_commit_transaction
*
* The primary function for committing a transaction to the log. This
@@ -173,7 +274,7 @@
struct buffer_head **wbuf = journal->j_wbuf;
int bufs;
int flags;
- int err;
+ int err = 0;
unsigned long blocknr;
char *tagp = NULL;
journal_header_t *header;
@@ -313,113 +414,7 @@
* Now start flushing things to disk, in the order they appear
* on the transaction lists. Data blocks go first.
*/
-
- err = 0;
- /*
- * Whenever we unlock the journal and sleep, things can get added
- * onto ->t_sync_datalist, so we have to keep looping back to
- * write_out_data until we *know* that the list is empty.
- */
- bufs = 0;
- /*
- * Cleanup any flushed data buffers from the data list. Even in
- * abort mode, we want to flush this out as soon as possible.
- */
-write_out_data:
- cond_resched();
- spin_lock(&journal->j_list_lock);
-
- while (commit_transaction->t_sync_datalist) {
- struct buffer_head *bh;
-
- jh = commit_transaction->t_sync_datalist;
- commit_transaction->t_sync_datalist = jh->b_tnext;
- bh = jh2bh(jh);
- if (buffer_locked(bh)) {
- BUFFER_TRACE(bh, "locked");
- if (!inverted_lock(journal, bh))
- goto write_out_data;
- __journal_temp_unlink_buffer(jh);
- __journal_file_buffer(jh, commit_transaction,
- BJ_Locked);
- jbd_unlock_bh_state(bh);
- if (lock_need_resched(&journal->j_list_lock)) {
- spin_unlock(&journal->j_list_lock);
- goto write_out_data;
- }
- } else {
- if (buffer_dirty(bh)) {
- BUFFER_TRACE(bh, "start journal writeout");
- get_bh(bh);
- wbuf[bufs++] = bh;
- if (bufs == journal->j_wbufsize) {
- jbd_debug(2, "submit %d writes\n",
- bufs);
- spin_unlock(&journal->j_list_lock);
- ll_rw_block(SWRITE, bufs, wbuf);
- journal_brelse_array(wbuf, bufs);
- bufs = 0;
- goto write_out_data;
- }
- } else {
- BUFFER_TRACE(bh, "writeout complete: unfile");
- if (!inverted_lock(journal, bh))
- goto write_out_data;
- __journal_unfile_buffer(jh);
- jbd_unlock_bh_state(bh);
- journal_remove_journal_head(bh);
- put_bh(bh);
- if (lock_need_resched(&journal->j_list_lock)) {
- spin_unlock(&journal->j_list_lock);
- goto write_out_data;
- }
- }
- }
- }
-
- if (bufs) {
- spin_unlock(&journal->j_list_lock);
- ll_rw_block(SWRITE, bufs, wbuf);
- journal_brelse_array(wbuf, bufs);
- spin_lock(&journal->j_list_lock);
- }
-
- /*
- * Wait for all previously submitted IO to complete.
- */
- while (commit_transaction->t_locked_list) {
- struct buffer_head *bh;
-
- jh = commit_transaction->t_locked_list->b_tprev;
- bh = jh2bh(jh);
- get_bh(bh);
- if (buffer_locked(bh)) {
- spin_unlock(&journal->j_list_lock);
- wait_on_buffer(bh);
- if (unlikely(!buffer_uptodate(bh)))
- err = -EIO;
- spin_lock(&journal->j_list_lock);
- }
- if (!inverted_lock(journal, bh)) {
- put_bh(bh);
- spin_lock(&journal->j_list_lock);
- continue;
- }
- if (buffer_jbd(bh) && jh->b_jlist == BJ_Locked) {
- __journal_unfile_buffer(jh);
- jbd_unlock_bh_state(bh);
- journal_remove_journal_head(bh);
- put_bh(bh);
- } else {
- jbd_unlock_bh_state(bh);
- }
- put_bh(bh);
- cond_resched_lock(&journal->j_list_lock);
- }
- spin_unlock(&journal->j_list_lock);
-
- if (err)
- __journal_abort_hard(journal);
+ write_out_sync_data(journal, commit_transaction);
journal_write_revoke_records(journal, commit_transaction);
next prev parent reply other threads:[~2006-05-24 9:14 UTC|newest]
Thread overview: 19+ messages / expand[flat|nested] mbox.gz Atom feed top
2006-05-18 8:25 [PATCH] Change ll_rw_block() calls in JBD Zoltan Menyhart
2006-05-18 13:45 ` Jan Kara
2006-05-18 15:11 ` Zoltan Menyhart
2006-05-18 22:25 ` Stephen C. Tweedie
2006-05-19 10:01 ` Zoltan Menyhart
2006-05-19 12:26 ` Stephen C. Tweedie
2006-05-19 1:30 ` Jan Kara
2006-05-19 12:33 ` Zoltan Menyhart
2006-05-19 15:05 ` Stephen C. Tweedie
2006-05-19 15:06 ` Stephen C. Tweedie
2006-05-24 17:33 ` Jan Kara
2006-05-30 15:36 ` Zoltan Menyhart
2006-05-30 16:40 ` Jan Kara
2006-05-23 16:01 ` Zoltan Menyhart
2006-05-24 9:14 ` Zoltan Menyhart [this message]
2006-05-24 17:18 ` Jan Kara
[not found] ` <447F13B3.6050505@bull.net>
[not found] ` <20060601162751.GH26933@atrey.karlin.mff.cuni.cz>
[not found] ` <44801E16.3040300@bull.net>
[not found] ` <20060602134923.GA1644@atrey.karlin.mff.cuni.cz>
2006-06-20 16:33 ` Zoltan Menyhart
2006-06-21 0:09 ` Jan Kara
-- strict thread matches above, loose matches on Subject: below --
2005-07-11 15:52 Jan Kara
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=447423F7.5000002@bull.net \
--to=zoltan.menyhart@bull.net \
--cc=jack@suse.cz \
--cc=linux-kernel@vger.kernel.org \
--cc=sct@redhat.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.