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 Direct IO bugfix patch
Date: Thu, 13 Feb 2003 21:31:53 +0300 [thread overview]
Message-ID: <3E4BE499.90305@namesys.com> (raw)
[-- Attachment #1: Type: text/plain, Size: 11 bytes --]
--
Hans
[-- Attachment #2: 2.4 patch to forward --]
[-- Type: message/rfc822, Size: 5314 bytes --]
From: Oleg Drokin <green@namesys.com>
To: reiser@namesys.com
Subject: 2.4 patch to forward
Date: Thu, 13 Feb 2003 16:33:06 +0300
Message-ID: <20030213163305.A4419@namesys.com>
Hello!
This is the fix for the problem where DIRECT IO on a file that
later will be tail-packed can cause reiserfs to crash
in 2.4 kernels.
It can be pulled from bk://namesys.com/bk/reiser3-linux-2.4-directio-fix
Please apply, thanks.
Diffstat:
inode.c | 43 +++++++++++++++++++++++++++++++++++--------
tail_conversion.c | 4 +++-
2 files changed, 38 insertions(+), 9 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.967 -> 1.968
# fs/reiserfs/inode.c 1.41 -> 1.42
# fs/reiserfs/tail_conversion.c 1.15 -> 1.16
#
# The following is the BitKeeper ChangeSet Log
# --------------------------------------------
# 03/02/13 green@angband.namesys.com 1.968
# reiserfs: Fix DIRECT IO interference with tail packing
# --------------------------------------------
#
diff -Nru a/fs/reiserfs/inode.c b/fs/reiserfs/inode.c
--- a/fs/reiserfs/inode.c Thu Feb 13 16:22:56 2003
+++ b/fs/reiserfs/inode.c Thu Feb 13 16:22:56 2003
@@ -418,6 +418,7 @@
struct buffer_head * bh_result, int create) {
int ret ;
+ bh_result->b_page = NULL;
ret = reiserfs_get_block(inode, block, bh_result, create) ;
/* don't allow direct io onto tail pages */
@@ -428,6 +429,14 @@
reiserfs_unmap_buffer(bh_result);
ret = -EINVAL ;
}
+ /* Possible unpacked tail. Flush the data before pages have
+ disappeared */
+ if (inode->u.reiserfs_i.i_flags & i_pack_on_close_mask) {
+ lock_kernel();
+ reiserfs_commit_for_inode(inode);
+ inode->u.reiserfs_i.i_flags &= ~i_pack_on_close_mask;
+ unlock_kernel();
+ }
return ret ;
}
@@ -566,7 +575,12 @@
return ret;
}
- inode->u.reiserfs_i.i_flags |= i_pack_on_close_mask;
+ /* If file is of such a size, that it might have a tail and tails are enabled
+ ** we should mark it as possibly needing tail packing on close
+ */
+ if ( (have_large_tails (inode->i_sb) && inode->i_size < block_size (inode)*4) ||
+ (have_small_tails (inode->i_sb) && inode->i_size < block_size(inode)) )
+ inode->u.reiserfs_i.i_flags |= i_pack_on_close_mask;
windex = push_journal_writer("reiserfs_get_block") ;
@@ -757,15 +771,21 @@
*/
mark_buffer_uptodate (unbh, 1);
- /* we've converted the tail, so we must
- ** flush unbh before the transaction commits
+ /* unbh->b_page == NULL in case of DIRECT_IO request, this means
+ buffer will disappear shortly, so it should not be added to
+ any of our lists.
*/
- add_to_flushlist(inode, unbh) ;
+ if ( unbh->b_page ) {
+ /* we've converted the tail, so we must
+ ** flush unbh before the transaction commits
+ */
+ add_to_flushlist(inode, unbh) ;
- /* mark it dirty now to prevent commit_write from adding
- ** this buffer to the inode's dirty buffer list
- */
- __mark_buffer_dirty(unbh) ;
+ /* mark it dirty now to prevent commit_write from adding
+ ** this buffer to the inode's dirty buffer list
+ */
+ __mark_buffer_dirty(unbh) ;
+ }
//inode->i_blocks += inode->i_sb->s_blocksize / 512;
//mark_tail_converted (inode);
@@ -2062,6 +2082,13 @@
if (pos > inode->i_size) {
struct reiserfs_transaction_handle th ;
lock_kernel();
+ /* If the file have grown beyond the border where it
+ can have a tail, unmark it as needing a tail
+ packing */
+ if ( (have_large_tails (inode->i_sb) && inode->i_size < block_size (inode)*4) ||
+ (have_small_tails (inode->i_sb) && inode->i_size < block_size(inode)) )
+ inode->u.reiserfs_i.i_flags &= ~i_pack_on_close_mask;
+
journal_begin(&th, inode->i_sb, 1) ;
reiserfs_update_inode_transaction(inode) ;
inode->i_size = pos ;
diff -Nru a/fs/reiserfs/tail_conversion.c b/fs/reiserfs/tail_conversion.c
--- a/fs/reiserfs/tail_conversion.c Thu Feb 13 16:22:56 2003
+++ b/fs/reiserfs/tail_conversion.c Thu Feb 13 16:22:56 2003
@@ -105,8 +105,10 @@
/* we only send the unbh pointer if the buffer is not up to date.
** this avoids overwriting good data from writepage() with old data
** from the disk or buffer cache
+ ** Special case: unbh->b_page will be NULL if we are coming through
+ ** DIRECT_IO handler here.
*/
- if (buffer_uptodate(unbh) || Page_Uptodate(unbh->b_page)) {
+ if ( !unbh->b_page || buffer_uptodate(unbh) || Page_Uptodate(unbh->b_page)) {
up_to_date_bh = NULL ;
} else {
up_to_date_bh = unbh ;
Bye,
Oleg
reply other threads:[~2003-02-13 18:22 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=3E4BE499.90305@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.