All of lore.kernel.org
 help / color / mirror / Atom feed
From: Hans Reiser <reiser@namesys.com>
To: Marcelo Tosatti <marcelo@conectiva.com.br>
Cc: Linux Kernel Mailing List <linux-kernel@vger.kernel.org>
Subject: [BK] [2.4] reiserfs: fix one more directio vs tails problem, resend]
Date: Mon, 12 May 2003 23:31:45 +0400	[thread overview]
Message-ID: <3EBFF6A1.2080501@namesys.com> (raw)

[-- Attachment #1: Type: text/plain, Size: 11 bytes --]


-- 
Hans


[-- Attachment #2: [2.4] reiserfs: fix one more directio vs tails problem, resend --]
[-- Type: message/rfc822, Size: 7943 bytes --]

From: Oleg Drokin <green@namesys.com>
To: reiser@namesys.com
Subject: [2.4] reiserfs: fix one more directio vs tails problem, resend
Date: Mon, 12 May 2003 18:01:30 +0400
Message-ID: <20030512140130.GA6665@namesys.com>

Hello!

    This changeset fixes another set problems related to directio vs packed tails.
    Thanks to Mingming Cao <mcao@us.ibm.com> for bringing the issue to our attention.
    Most of the patch was made by Chris Mason.

    Please pull from bk://namesys.com/bk/reiser3-linux-2.4-directiofix2

Diffstat:
 fs/reiserfs/inode.c           |   12 ++++++-
 fs/reiserfs/journal.c         |   66 +++++++++++++++++++++++++++---------------
 fs/reiserfs/tail_conversion.c |    1
 include/linux/reiserfs_fs.h   |    2 +
 include/linux/reiserfs_fs_i.h |    7 ++++
 5 files changed, 63 insertions(+), 25 deletions(-)

Plain text patch:

# This is a BitKeeper generated patch for the following project:
# Project Name: Linux kernel tree
# This patch format is intended for GNU patch command version 2.5 or higher.
# This patch includes the following deltas:
#	           ChangeSet	1.1158  -> 1.1159 
#	include/linux/reiserfs_fs_i.h	1.8     -> 1.9    
#	 fs/reiserfs/inode.c	1.42    -> 1.43   
#	fs/reiserfs/tail_conversion.c	1.16    -> 1.17   
#	fs/reiserfs/journal.c	1.28    -> 1.29   
#	include/linux/reiserfs_fs.h	1.26    -> 1.27   
#
# The following is the BitKeeper ChangeSet Log
# --------------------------------------------
# 03/05/03	green@angband.namesys.com	1.1159
# reiserfs: Fix another O_DIRECT vs tails problem. Mostly by Chris Mason.
# Thanks to Mingming Cao <mcao@us.ibm.com> for bringing the issue to our attention.
# --------------------------------------------
#
diff -Nru a/fs/reiserfs/inode.c b/fs/reiserfs/inode.c
--- a/fs/reiserfs/inode.c	Mon May 12 18:00:53 2003
+++ b/fs/reiserfs/inode.c	Mon May 12 18:00:53 2003
@@ -469,7 +469,7 @@
     tail_end = (tail_start | (bh_result->b_size - 1)) + 1 ;
 
     index = tail_offset >> PAGE_CACHE_SHIFT ;
-    if (index != hole_page->index) {
+    if ( !hole_page || index != hole_page->index) {
 	tail_page = grab_cache_page(inode->i_mapping, index) ;
 	retval = -ENOMEM;
 	if (!tail_page) {
@@ -1810,7 +1810,12 @@
 	    flush_dcache_page(page) ;
 	    kunmap(page) ;
 	    if (buffer_mapped(bh) && bh->b_blocknr != 0) {
-	        mark_buffer_dirty(bh) ;
+	        if (!atomic_set_buffer_dirty(bh)) {
+			set_buffer_flushtime(bh);
+			refile_buffer(bh);
+			buffer_insert_inode_data_queue(bh, p_s_inode);
+			balance_dirty();
+		}
 	    }
 	}
 	UnlockPage(page) ;
@@ -2158,6 +2163,9 @@
                               struct kiobuf *iobuf, unsigned long blocknr,
 			      int blocksize) 
 {
+    lock_kernel();
+    reiserfs_commit_for_tail(inode);
+    unlock_kernel();
     return generic_direct_IO(rw, inode, iobuf, blocknr, blocksize,
                              reiserfs_get_block_direct_io) ;
 }
diff -Nru a/fs/reiserfs/journal.c b/fs/reiserfs/journal.c
--- a/fs/reiserfs/journal.c	Mon May 12 18:00:53 2003
+++ b/fs/reiserfs/journal.c	Mon May 12 18:00:53 2003
@@ -2655,32 +2655,52 @@
   inode->u.reiserfs_i.i_trans_id = SB_JOURNAL(inode->i_sb)->j_trans_id ;
 }
 
-static int reiserfs_inode_in_this_transaction(struct inode *inode) {
-  if (inode->u.reiserfs_i.i_trans_id == SB_JOURNAL(inode->i_sb)->j_trans_id || 
-      inode->u.reiserfs_i.i_trans_id == 0) {
-    return 1; 
-  } 
-  return 0 ;
+void reiserfs_update_tail_transaction(struct inode *inode) {
+  
+  inode->u.reiserfs_i.i_tail_trans_index = SB_JOURNAL_LIST_INDEX(inode->i_sb);
+
+  inode->u.reiserfs_i.i_tail_trans_id = SB_JOURNAL(inode->i_sb)->j_trans_id ;
+}
+
+static void __commit_trans_index(struct inode *inode, unsigned long id,
+                                 unsigned long index) 
+{
+    struct reiserfs_journal_list *jl ;
+    struct reiserfs_transaction_handle th ;
+    struct super_block *sb = inode->i_sb ;
+
+    jl = SB_JOURNAL_LIST(sb) + index;
+
+    /* is it from the current transaction, or from an unknown transaction? */
+    if (id == SB_JOURNAL(sb)->j_trans_id) {
+	journal_join(&th, sb, 1) ;
+	journal_end_sync(&th, sb, 1) ;
+    } else if (jl->j_trans_id == id) {
+	flush_commit_list(sb, jl, 1) ;
+    }
+    /* if the transaction id does not match, this list is long since flushed
+    ** and we don't have to do anything here
+    */
 }
+void reiserfs_commit_for_tail(struct inode *inode) {
+    unsigned long id = inode->u.reiserfs_i.i_tail_trans_id;
+    unsigned long index = inode->u.reiserfs_i.i_tail_trans_index;
 
+    /* for tails, if this info is unset there's nothing to commit */
+    if (id && index)
+	__commit_trans_index(inode, id, index);
+}
 void reiserfs_commit_for_inode(struct inode *inode) {
-  struct reiserfs_journal_list *jl ;
-  struct reiserfs_transaction_handle th ;
-  struct super_block *sb = inode->i_sb ;
-
-  jl = SB_JOURNAL_LIST(sb) + inode->u.reiserfs_i.i_trans_index ;
-
-  /* is it from the current transaction, or from an unknown transaction? */
-  if (reiserfs_inode_in_this_transaction(inode)) {
-    journal_join(&th, sb, 1) ;
-    reiserfs_update_inode_transaction(inode) ;
-    journal_end_sync(&th, sb, 1) ;
-  } else if (jl->j_trans_id == inode->u.reiserfs_i.i_trans_id) {
-    flush_commit_list(sb, jl, 1) ;
-  }
-  /* if the transaction id does not match, this list is long since flushed
-  ** and we don't have to do anything here
-  */
+    unsigned long id = inode->u.reiserfs_i.i_trans_id;
+    unsigned long index = inode->u.reiserfs_i.i_trans_index;
+
+    /* for the whole inode, assume unset id or index means it was
+     * changed in the current transaction.  More conservative
+     */
+    if (!id || !index)
+	reiserfs_update_inode_transaction(inode) ;
+
+    __commit_trans_index(inode, id, index);
 }
 
 void reiserfs_restore_prepared_buffer(struct super_block *p_s_sb, 
diff -Nru a/fs/reiserfs/tail_conversion.c b/fs/reiserfs/tail_conversion.c
--- a/fs/reiserfs/tail_conversion.c	Mon May 12 18:00:53 2003
+++ b/fs/reiserfs/tail_conversion.c	Mon May 12 18:00:53 2003
@@ -133,6 +133,7 @@
 
     inode->u.reiserfs_i.i_first_direct_byte = U32_MAX;
 
+    reiserfs_update_tail_transaction(inode);
     return 0;
 }
 
diff -Nru a/include/linux/reiserfs_fs.h b/include/linux/reiserfs_fs.h
--- a/include/linux/reiserfs_fs.h	Mon May 12 18:00:53 2003
+++ b/include/linux/reiserfs_fs.h	Mon May 12 18:00:53 2003
@@ -1558,7 +1558,9 @@
 #define JOURNAL_BUFFER(j,n) ((j)->j_ap_blocks[((j)->j_start + (n)) % JOURNAL_BLOCK_COUNT])
 
 void reiserfs_commit_for_inode(struct inode *) ;
+void reiserfs_commit_for_tail(struct inode *) ;
 void reiserfs_update_inode_transaction(struct inode *) ;
+void reiserfs_update_tail_transaction(struct inode *) ;
 void reiserfs_wait_on_write_block(struct super_block *s) ;
 void reiserfs_block_writes(struct reiserfs_transaction_handle *th) ;
 void reiserfs_allow_writes(struct super_block *s) ;
diff -Nru a/include/linux/reiserfs_fs_i.h b/include/linux/reiserfs_fs_i.h
--- a/include/linux/reiserfs_fs_i.h	Mon May 12 18:00:53 2003
+++ b/include/linux/reiserfs_fs_i.h	Mon May 12 18:00:53 2003
@@ -53,6 +53,13 @@
     ** flushed */
     unsigned long i_trans_id ;
     unsigned long i_trans_index ;
+
+    /* direct io needs to make sure the tail is on disk to avoid
+     * buffer alias problems.  This records the transaction last
+     * involved in a direct->indirect conversion for this file
+     */
+    unsigned long i_tail_trans_id;
+    unsigned long i_tail_trans_index;
 };
 
 #endif



                 reply	other threads:[~2003-05-12 19:19 UTC|newest]

Thread overview: [no followups] expand[flat|nested]  mbox.gz  Atom feed

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=3EBFF6A1.2080501@namesys.com \
    --to=reiser@namesys.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=marcelo@conectiva.com.br \
    /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.