All of lore.kernel.org
 help / color / mirror / Atom feed
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: Tue, 23 May 2006 18:01:22 +0200	[thread overview]
Message-ID: <447331D2.10004@bull.net> (raw)
In-Reply-To: <20060518134533.GA20159@atrey.karlin.mff.cuni.cz>

Please have a look at my version of the "write_out_data:" loop.

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-23 17:44:46.000000000 +0200
@@ -161,6 +161,104 @@
 }
 
 /*
+ * 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");
+					continue; /* Put on the BJ_Locked list */
+				}
+				if (test_clear_buffer_dirty(bh)){
+					BUFFER_TRACE(bh, "start journal wr");
+					get_bh(bh);
+					bh->b_end_io = end_buffer_write_sync;
+					submit_bh(WRITE, bh);
+					continue; /* Put on the BJ_Locked list */
+				}
+				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 +271,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 +411,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);
 

  parent reply	other threads:[~2006-05-23 16:01 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 [this message]
2006-05-24  9:14   ` Zoltan Menyhart
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=447331D2.10004@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.