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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox