# 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
[email protected] 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 ;