* [BK] [2.4] reiserfs: fix one more directio vs tails problem, resend]
@ 2003-05-12 19:31 Hans Reiser
0 siblings, 0 replies; only message in thread
From: Hans Reiser @ 2003-05-12 19:31 UTC (permalink / raw)
To: Marcelo Tosatti; +Cc: Linux Kernel Mailing List
[-- 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
^ permalink raw reply [flat|nested] only message in thread
only message in thread, other threads:[~2003-05-12 19:19 UTC | newest]
Thread overview: (only message) (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2003-05-12 19:31 [BK] [2.4] reiserfs: fix one more directio vs tails problem, resend] Hans Reiser
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox