diff -Nru a/fs/reiserfs/inode.c b/fs/reiserfs/inode.c --- a/fs/reiserfs/inode.c Mon Aug 19 18:58:41 2002 +++ b/fs/reiserfs/inode.c Mon Aug 19 18:58:41 2002 @@ -757,15 +758,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) ; - - /* mark it dirty now to prevent commit_write from adding - ** this buffer to the inode's dirty buffer list - */ - __mark_buffer_dirty(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) ; + } //inode->i_blocks += inode->i_sb->s_blocksize / 512; //mark_tail_converted (inode); diff -Nru a/fs/reiserfs/tail_conversion.c b/fs/reiserfs/tail_conversion.c --- a/fs/reiserfs/tail_conversion.c Mon Aug 19 18:58:41 2002 +++ b/fs/reiserfs/tail_conversion.c Mon Aug 19 18:58:41 2002 @@ -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 ;