Thanks much Hifumi!

Chris, please comment on the patch.

Hans

Hifumi Hisashi wrote:

>   Hello.
>
>   I noticed that the Reiserfs has some problems related to meta-data
> journaling.
>   I suppose that transactions regarding meta-data should be written to
> a disk every
> meta-data change (for example, i_size is increased) in ordered-mode
> while synchronous
> writing is performed. But, it seems to me the Reiserfs does not do that.
>
>   I did a following test.
> 1, Mount the Reiserfs in ordered-mode.
> 2, Run the test program that opens a test file with O_SYNC|O_CREAT
> flag, and continues to
> write 4bytes data in busy loop. Every write() is and its file size is
> increasing.
> 3, While above the program is running, disconnect SCSI cable.
> 4, Hexdump a disk and see journal on a disk.
> 5, Reboot a system and again mount the Reiserfs in ordered mode.
>
>   I checked the size of file the test program created. I could not see
> whole content of this file
> because file size was shorter than it should be. The cause of this
> problem is that
> even though an i_size was changed, meta-data  was not logged to a
> journal area on disk
> under synchronous writing.
>
>   I did same test on Ext3, and there was no such a problem. Ext3(jbd)
> logged every change of
> an i_size while an O_SYNC writing was being performed.
>
>   Following patch fix this problem.
>
>  Signed-off-by :Hisashi Hifumi<[EMAIL PROTECTED]>
>
> diff -Nru linux-2.6.13/fs/reiserfs/file.c
> linux-2.6.13_fix/fs/reiserfs/file.c
> --- linux-2.6.13/fs/reiserfs/file.c    2005-08-29 08:41:01.000000000
> +0900
> +++ linux-2.6.13_fix/fs/reiserfs/file.c    2005-08-31
> 16:33:33.000000000 +0900
> @@ -819,7 +819,6 @@
>      int i;            // loop counter
>      int offset;        // Writing offset in page.
>      int orig_write_bytes = write_bytes;
> -    int sd_update = 0;
>
>      for (i = 0, offset = (pos & (PAGE_CACHE_SIZE - 1)); i < num_pages;
>           i++, offset = 0) {
> @@ -855,17 +854,17 @@
>
>          if (th->t_trans_id) {
>              reiserfs_write_lock(inode->i_sb);
> -            reiserfs_update_sd(th, inode);    // And update on-disk
> metadata
> +            status = journal_end(th, th->t_super,
> th->t_blocks_allocated);
> +                if (status)
> +                        retval = status;
>              reiserfs_write_unlock(inode->i_sb);
> -        } else
> -            inode->i_sb->s_op->dirty_inode(inode);
> -
> -        sd_update = 1;
> +        }
> +        mark_inode_dirty(inode);
> +        th->t_trans_id = 0;
>      }
>      if (th->t_trans_id) {
>          reiserfs_write_lock(inode->i_sb);
> -        if (!sd_update)
> -            reiserfs_update_sd(th, inode);
> +        reiserfs_update_sd(th, inode);
>          status = journal_end(th, th->t_super, th->t_blocks_allocated);
>          if (status)
>              retval = status;
> @@ -1526,10 +1525,13 @@
>          }
>      }
>
> -    if ((file->f_flags & O_SYNC) || IS_SYNC(inode))
> +    if ((file->f_flags & O_SYNC) || IS_SYNC(inode)) {
>          res =
>              generic_osync_inode(inode, file->f_mapping,
>                      OSYNC_METADATA | OSYNC_DATA);
> +        if (res)
> +            already_written = 0;
> +    }
>
>      up(&inode->i_sem);
>      reiserfs_async_progress_wait(inode->i_sb);
> diff -Nru linux-2.6.13/fs/reiserfs/inode.c
> linux-2.6.13_fix/fs/reiserfs/inode.c
> --- linux-2.6.13/fs/reiserfs/inode.c    2005-08-29 08:41:01.000000000
> +0900
> +++ linux-2.6.13_fix/fs/reiserfs/inode.c    2005-08-31
> 16:33:33.000000000 +0900
> @@ -1642,6 +1642,7 @@
>  {
>      struct reiserfs_transaction_handle th;
>      int jbegin_count = 1;
> +    int err = 0;
>
>      if (inode->i_sb->s_flags & MS_RDONLY)
>          return -EROFS;
> @@ -1654,11 +1655,11 @@
>          reiserfs_write_lock(inode->i_sb);
>          if (!journal_begin(&th, inode->i_sb, jbegin_count)) {
>              reiserfs_update_sd(&th, inode);
> -            journal_end_sync(&th, inode->i_sb, jbegin_count);
> +            err = journal_end_sync(&th, inode->i_sb, jbegin_count);
>          }
>          reiserfs_write_unlock(inode->i_sb);
>      }
> -    return 0;
> +    return err;
>  }
>
>  /* stat data of new object is inserted already, this inserts the item
>
> Thanks,
>
>

Reply via email to