diff -rup linux-2.4.7-pre6.A/fs/reiserfs/dir.c linux-2.4.7-pre6/fs/reiserfs/dir.c
--- linux-2.4.7-pre6.A/fs/reiserfs/dir.c        Wed Jul  4 13:45:54 2001
+++ linux-2.4.7-pre6/fs/reiserfs/dir.c  Tue Jul 17 18:20:31 2001
@@ -47,22 +47,10 @@ struct inode_operations reiserfs_dir_ino
};

int reiserfs_dir_fsync(struct file *filp, struct dentry *dentry, int datasync) {
-  int ret = 0 ;
-  int windex ;
-  struct reiserfs_transaction_handle th ;
-
  lock_kernel();
-
-  journal_begin(&th, dentry->d_inode->i_sb, 1) ;
-  windex = push_journal_writer("dir_fsync") ;
-  reiserfs_prepare_for_journal(th.t_super, SB_BUFFER_WITH_SB(th.t_super), 1) ;
-  journal_mark_dirty(&th, dentry->d_inode->i_sb, SB_BUFFER_WITH_SB (dentry->d_inode->i_sb)) ;
-  pop_journal_writer(windex) ;
-  journal_end_sync(&th, dentry->d_inode->i_sb, 1) ;
-
-  unlock_kernel();
-
-  return ret ;
+  reiserfs_commit_for_inode(dentry->d_inode) ;
+  unlock_kernel() ;
+  return 0 ;
}


diff -rup linux-2.4.7-pre6.A/fs/reiserfs/file.c linux-2.4.7-pre6/fs/reiserfs/file.c
--- linux-2.4.7-pre6.A/fs/reiserfs/file.c       Wed May  2 14:04:15 2001
+++ linux-2.4.7-pre6/fs/reiserfs/file.c Tue Jul 17 18:20:31 2001
@@ -50,6 +50,7 @@ static int reiserfs_file_release (struct
    lock_kernel() ;
    down (&inode->i_sem);
    journal_begin(&th, inode->i_sb, JOURNAL_PER_BALANCE_CNT * 3) ;
+    reiserfs_update_inode_transaction(inode) ;

#ifdef REISERFS_PREALLOCATE
    reiserfs_discard_prealloc (&th, inode);
@@ -83,10 +84,7 @@ static int reiserfs_sync_file(
                             int datasync
                             ) {
  struct inode * p_s_inode = p_s_dentry->d_inode;
-  struct reiserfs_transaction_handle th ;
  int n_err = 0;
-  int windex ;
-  int jbegin_count = 1 ;

  lock_kernel() ;

@@ -94,14 +92,9 @@ static int reiserfs_sync_file(
      BUG ();

  n_err = fsync_inode_buffers(p_s_inode) ;
-  /* commit the current transaction to flush any metadata
-  ** changes.  sys_fsync takes care of flushing the dirty pages for us
-  */
-  journal_begin(&th, p_s_inode->i_sb, jbegin_count) ;
-  windex = push_journal_writer("sync_file") ;
-  reiserfs_update_sd(&th, p_s_inode);
-  pop_journal_writer(windex) ;
-  journal_end_sync(&th, p_s_inode->i_sb,jbegin_count) ;
+
+  reiserfs_commit_for_inode(p_s_inode) ;
+
  unlock_kernel() ;
  return ( n_err < 0 ) ? -EIO : 0;
}
diff -rup linux-2.4.7-pre6.A/fs/reiserfs/inode.c linux-2.4.7-pre6/fs/reiserfs/inode.c
--- linux-2.4.7-pre6.A/fs/reiserfs/inode.c      Tue Jul 17 18:19:36 2001
+++ linux-2.4.7-pre6/fs/reiserfs/inode.c        Tue Jul 17 18:20:31 2001
@@ -41,6 +41,7 @@ void reiserfs_delete_inode (struct inode
       down (&inode->i_sem);

       journal_begin(&th, inode->i_sb, jbegin_count) ;
+       reiserfs_update_inode_transaction(inode) ;
       windex = push_journal_writer("delete_inode") ;

       reiserfs_delete_object (&th, inode);
@@ -232,6 +233,7 @@ int file_capable (struct inode * inode,
  reiserfs_update_sd(th, inode) ;
  journal_end(th, s, len) ;
  journal_begin(th, s, len) ;
+  reiserfs_update_inode_transaction(inode) ;
}

// it is called by get_block when create == 0. Returns block number
@@ -567,6 +569,7 @@ int reiserfs_get_block (struct inode * i
                 TYPE_ANY, 3/*key length*/);
    if ((new_offset + inode->i_sb->s_blocksize) >= inode->i_size) {
       journal_begin(&th, inode->i_sb, jbegin_count) ;
+       reiserfs_update_inode_transaction(inode) ;
       transaction_started = 1 ;
    }
 research:
@@ -591,6 +594,7 @@ int reiserfs_get_block (struct inode * i
       if (!transaction_started) {
           pathrelse(&path) ;
           journal_begin(&th, inode->i_sb, jbegin_count) ;
+           reiserfs_update_inode_transaction(inode) ;
           transaction_started = 1 ;
           goto research ;
       }
@@ -658,6 +662,7 @@ int reiserfs_get_block (struct inode * i
       */
       pathrelse(&path) ;
       journal_begin(&th, inode->i_sb, jbegin_count) ;
+       reiserfs_update_inode_transaction(inode) ;
       transaction_started = 1 ;
       goto research;
    }
@@ -1258,6 +1263,10 @@ void reiserfs_dirty_inode (struct inode
        return ;
    }
    lock_kernel() ;
+
+    /* this is really only used for atime updates, so they don't have
+    ** to be included in O_SYNC or fsync
+    */
    journal_begin(&th, inode->i_sb, 1) ;
    reiserfs_update_sd (&th, inode);
    journal_end(&th, inode->i_sb, 1) ;
@@ -1623,6 +1632,7 @@ void reiserfs_truncate_file(struct inode
    ** (it will unmap bh if it packs).
    */
    journal_begin(&th, p_s_inode->i_sb,  JOURNAL_PER_BALANCE_CNT * 2 ) ;
+    reiserfs_update_inode_transaction(p_s_inode) ;
    windex = push_journal_writer("reiserfs_vfs_truncate_file") ;
    reiserfs_do_truncate (&th, p_s_inode, page, update_timestamps) ;
    pop_journal_writer(windex) ;
@@ -1669,6 +1679,7 @@ static int map_block_for_writepage(struc
start_over:
    lock_kernel() ;
    journal_begin(&th, inode->i_sb, jbegin_count) ;
+    reiserfs_update_inode_transaction(inode) ;

    make_cpu_key(&key, inode, byte_offset, TYPE_ANY, 3) ;

@@ -1900,22 +1911,34 @@ static int reiserfs_aop_bmap(struct addr
static int reiserfs_commit_write(struct file *f, struct page *page,
                                unsigned from, unsigned to) {
    struct inode *inode = page->mapping->host;
+    loff_t pos = ((loff_t)page->index << PAGE_CACHE_SHIFT) + to;
    int ret ;

    reiserfs_wait_on_write_block(inode->i_sb) ;
+
+    /* generic_commit_write does this for us, but does not update the
+    ** transaction tracking stuff when the size changes.  So, we have
+    ** to do the i_size updates here.
+    */
+    if (pos > inode->i_size) {
+       struct reiserfs_transaction_handle th ;
+       lock_kernel() ;
+       journal_begin(&th, inode->i_sb, 1) ;
+       reiserfs_update_inode_transaction(inode) ;
+       inode->i_size = pos ;
+       reiserfs_update_sd(&th, inode) ;
+       journal_end(&th, inode->i_sb, 1) ;
+       unlock_kernel() ;
+    }
+
    ret = generic_commit_write(f, page, from, to) ;

    /* we test for O_SYNC here so we can commit the transaction
    ** for any packed tails the file might have had
    */
    if (f->f_flags & O_SYNC) {
-       struct reiserfs_transaction_handle th ;
       lock_kernel() ;
-       journal_begin(&th, inode->i_sb, 1) ;
-       reiserfs_prepare_for_journal(inode->i_sb,
-                                    SB_BUFFER_WITH_SB(inode->i_sb), 1) ;
-       journal_mark_dirty(&th, inode->i_sb, SB_BUFFER_WITH_SB(inode->i_sb)) ;
-       journal_end_sync(&th, inode->i_sb, 1) ;
+       reiserfs_commit_for_inode(inode) ;
       unlock_kernel() ;
    }
    return ret ;
diff -rup linux-2.4.7-pre6.A/fs/reiserfs/journal.c linux-2.4.7-pre6/fs/reiserfs/journal.c
--- linux-2.4.7-pre6.A/fs/reiserfs/journal.c    Tue Jul 17 18:19:36 2001
+++ linux-2.4.7-pre6/fs/reiserfs/journal.c      Tue Jul 17 18:20:31 2001
@@ -2313,6 +2313,11 @@ static int can_dirty(struct reiserfs_jou
** will wait until the current transaction is done/commited before returning
*/
int journal_end_sync(struct reiserfs_transaction_handle *th, struct super_block *p_s_sb, unsigned long nblocks) {
+
+  if (SB_JOURNAL(p_s_sb)->j_len == 0) {
+    reiserfs_prepare_for_journal(p_s_sb, SB_BUFFER_WITH_SB(p_s_sb), 1) ;
+    journal_mark_dirty(th, p_s_sb, SB_BUFFER_WITH_SB(p_s_sb)) ;
+  }
  return do_journal_end(th, p_s_sb, nblocks, COMMIT_NOW | WAIT) ;
}

@@ -2603,6 +2608,41 @@ int journal_mark_freed(struct reiserfs_t
    }
  }
  return 0 ;
+}
+
+void reiserfs_update_inode_transaction(struct inode *inode) {
+
+  inode->u.reiserfs_i.i_trans_index = SB_JOURNAL_LIST_INDEX(inode->i_sb);
+
+  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_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
+  */
}

void reiserfs_restore_prepared_buffer(struct super_block *p_s_sb,
diff -rup linux-2.4.7-pre6.A/fs/reiserfs/namei.c linux-2.4.7-pre6/fs/reiserfs/namei.c
--- linux-2.4.7-pre6.A/fs/reiserfs/namei.c      Wed Jul  4 13:45:55 2001
+++ linux-2.4.7-pre6/fs/reiserfs/namei.c        Tue Jul 17 18:20:31 2001
@@ -554,6 +554,8 @@ int reiserfs_create (struct inode * dir,
       journal_end(&th, dir->i_sb, jbegin_count) ;
       return retval;
    }
+    reiserfs_update_inode_transaction(inode) ;
+    reiserfs_update_inode_transaction(dir) ;

    inode->i_op = &reiserfs_file_inode_operations;
    inode->i_fop = &reiserfs_file_operations;
@@ -613,6 +615,9 @@ int reiserfs_mknod (struct inode * dir,
    //FIXME: needed for block and char devices only
    reiserfs_update_sd (&th, inode);

+    reiserfs_update_inode_transaction(inode) ;
+    reiserfs_update_inode_transaction(dir) ;
+
    retval = reiserfs_add_entry (&th, dir, dentry->d_name.name, dentry->d_name.len,
                                inode, 1/*visible*/);
    if (retval) {
@@ -668,6 +673,8 @@ int reiserfs_mkdir (struct inode * dir,
       journal_end(&th, dir->i_sb, jbegin_count) ;
       return retval;
    }
+    reiserfs_update_inode_transaction(inode) ;
+    reiserfs_update_inode_transaction(dir) ;

    inode->i_op = &reiserfs_dir_inode_operations;
    inode->i_fop = &reiserfs_dir_operations;
@@ -736,6 +743,9 @@ int reiserfs_rmdir (struct inode * dir,
    }
    inode = dentry->d_inode;

+    reiserfs_update_inode_transaction(inode) ;
+    reiserfs_update_inode_transaction(dir) ;
+
    if (de.de_objectid != inode->i_ino) {
       // FIXME: compare key of an object and a key found in the
       // entry
@@ -809,6 +819,9 @@ int reiserfs_unlink (struct inode * dir,
    }
    inode = dentry->d_inode;

+    reiserfs_update_inode_transaction(inode) ;
+    reiserfs_update_inode_transaction(dir) ;
+
    if (de.de_objectid != inode->i_ino) {
       // FIXME: compare key of an object and a key found in the
       // entry
@@ -898,6 +911,9 @@ int reiserfs_symlink (struct inode * dir
       return retval;
    }

+    reiserfs_update_inode_transaction(inode) ;
+    reiserfs_update_inode_transaction(dir) ;
+
    inode->i_op = &page_symlink_inode_operations;
    inode->i_mapping->a_ops = &reiserfs_address_space_operations;

@@ -953,6 +969,10 @@ int reiserfs_link (struct dentry * old_d
    /* create new entry */
    retval = reiserfs_add_entry (&th, dir, dentry->d_name.name, dentry->d_name.len,
                                inode, 1/*visible*/);
+
+    reiserfs_update_inode_transaction(inode) ;
+    reiserfs_update_inode_transaction(dir) ;
+
    if (retval) {
       pop_journal_writer(windex) ;
       journal_end(&th, dir->i_sb, jbegin_count) ;
@@ -1098,6 +1118,10 @@ int reiserfs_rename (struct inode * old_
       return retval;
    }

+    reiserfs_update_inode_transaction(old_dir) ;
+    reiserfs_update_inode_transaction(new_dir) ;
+    if (new_inode)
+       reiserfs_update_inode_transaction(new_inode) ;

    while (1) {
       // look for old name using corresponding entry key (found by reiserfs_find_entry)
diff -rup linux-2.4.7-pre6.A/fs/reiserfs/stree.c linux-2.4.7-pre6/fs/reiserfs/stree.c
--- linux-2.4.7-pre6.A/fs/reiserfs/stree.c      Tue Jul 17 18:19:36 2001
+++ linux-2.4.7-pre6/fs/reiserfs/stree.c        Tue Jul 17 18:20:31 2001
@@ -1917,6 +1917,7 @@ void reiserfs_do_truncate (struct reiser

         journal_end(th, p_s_inode->i_sb, orig_len_alloc) ;
         journal_begin(th, p_s_inode->i_sb, orig_len_alloc) ;
+         reiserfs_update_inode_transaction(p_s_inode) ;
       }
    } while ( n_file_size > ROUND_UP (n_new_file_size) &&
             search_for_position_by_key(p_s_inode->i_sb, &s_item_key, &s_search_path) == POSITION_FOUND )  ;
diff -rup linux-2.4.7-pre6.A/include/linux/reiserfs_fs.h linux-2.4.7-pre6/include/linux/reiserfs_fs.h
--- linux-2.4.7-pre6.A/include/linux/reiserfs_fs.h      Tue Jul 17 18:19:36 2001
+++ linux-2.4.7-pre6/include/linux/reiserfs_fs.h        Tue Jul 17 18:20:31 2001
@@ -1576,6 +1576,8 @@ extern wait_queue_head_t reiserfs_commit
*/
#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_update_inode_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 -rup linux-2.4.7-pre6.A/include/linux/reiserfs_fs_i.h linux-2.4.7-pre6/include/linux/reiserfs_fs_i.h
--- linux-2.4.7-pre6.A/include/linux/reiserfs_fs_i.h    Tue Jul 17 18:19:36 2001
+++ linux-2.4.7-pre6/include/linux/reiserfs_fs_i.h      Tue Jul 17 18:20:31 2001
@@ -40,6 +40,12 @@ struct reiserfs_inode_info {
                                   is a comment you should make.... -Hans */
  //nopack-attribute
  int nopack;
+
+  /* we use these for fsync or O_SYNC to decide which transaction needs
+  ** to be committed in order for this inode to be properly flushed
+  */
+  unsigned long i_trans_id ;
+  unsigned long i_trans_index ;
};