lkml.org 
[lkml]   [2017]   [Jun]   [19]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH 3.10 188/268] cancel the setfilesize transation when io error happen
    Date
    From: Zhaohongjiang <zhaohongjiang@huawei.com>

    commit 510c971aeaaebf0dce7a45d16dc3eb9eab1c8340 upstream.

    Commit 5cb13dcd0fac071b45c4bebe1801a08ff0d89cad upstream.

    When I ran xfstest/073 case, the remount process was blocked to wait
    transactions to be zero. I found there was a io error happened, and
    the setfilesize transaction was not released properly. We should add
    the changes to cancel the io error in this case.

    Reproduction steps:
    1. dd if=/dev/zero of=xfs1.img bs=1M count=2048
    2. mkfs.xfs xfs1.img
    3. losetup -f ./xfs1.img /dev/loop0
    4. mount -t xfs /dev/loop0 /home/test_dir/
    5. mkdir /home/test_dir/test
    6. mkfs.xfs -dfile,name=image,size=2g
    7. mount -t xfs -o loop image /home/test_dir/test
    8. cp a file bigger than 2g to /home/test_dir/test
    9. mount -t xfs -o remount,ro /home/test_dir/test

    [ dchinner: moved io error detection to xfs_setfilesize_ioend() after
    transaction context restoration. ]

    [ nborisov: Adjusted context for 3.12 ]

    Signed-off-by: Zhao Hongjiang <zhaohongjiang@huawei.com>
    Signed-off-by: Dave Chinner <david@fromorbit.com>
    Reviewed-by: Christoph Hellwig <hch@lst.de>
    Signed-off-by: Nikolay Borisov <nborisov@suse.com>
    Signed-off-by: Willy Tarreau <w@1wt.eu>
    ---
    fs/xfs/xfs_aops.c | 13 +++++++++++--
    1 file changed, 11 insertions(+), 2 deletions(-)

    diff --git a/fs/xfs/xfs_aops.c b/fs/xfs/xfs_aops.c
    index cfbb4c1..d738a7b 100644
    --- a/fs/xfs/xfs_aops.c
    +++ b/fs/xfs/xfs_aops.c
    @@ -158,6 +158,12 @@ xfs_setfilesize(
    rwsem_acquire_read(&VFS_I(ip)->i_sb->s_writers.lock_map[SB_FREEZE_FS-1],
    0, 1, _THIS_IP_);

    + /* we abort the update if there was an IO error */
    + if (ioend->io_error) {
    + xfs_trans_cancel(tp, 0);
    + return ioend->io_error;
    + }
    +
    xfs_ilock(ip, XFS_ILOCK_EXCL);
    isize = xfs_new_eof(ip, ioend->io_offset + ioend->io_size);
    if (!isize) {
    @@ -213,14 +219,17 @@ xfs_end_io(
    ioend->io_error = -EIO;
    goto done;
    }
    - if (ioend->io_error)
    - goto done;

    /*
    * For unwritten extents we need to issue transactions to convert a
    * range to normal written extens after the data I/O has finished.
    + * Detecting and handling completion IO errors is done individually
    + * for each case as different cleanup operations need to be performed
    + * on error.
    */
    if (ioend->io_type == XFS_IO_UNWRITTEN) {
    + if (ioend->io_error)
    + goto done;
    error = xfs_iomap_write_unwritten(ip, ioend->io_offset,
    ioend->io_size);
    } else if (ioend->io_isdirect && xfs_ioend_is_append(ioend)) {
    --
    2.8.0.rc2.1.gbe9624a
    \
     
     \ /
      Last update: 2017-06-19 21:23    [W:4.074 / U:0.084 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site