lkml.org 
[lkml]   [2022]   [Jan]   [31]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH 5.16 008/200] btrfs: update writeback index when starting defrag
    Date
    From: Filipe Manana <fdmanana@suse.com>

    commit 27cdfde181bcacd226c230b2fd831f6f5b8c215f upstream.

    When starting a defrag, we should update the writeback index of the
    inode's mapping in case it currently has a value beyond the start of the
    range we are defragging. This can help performance and often result in
    getting less extents after writeback - for e.g., if the current value
    of the writeback index sits somewhere in the middle of a range that
    gets dirty by the defrag, then after writeback we can get two smaller
    extents instead of a single, larger extent.

    We used to have this before the refactoring in 5.16, but it was removed
    without any reason to do so. Originally it was added in kernel 3.1, by
    commit 2a0f7f5769992b ("Btrfs: fix recursive auto-defrag"), in order to
    fix a loop with autodefrag resulting in dirtying and writing pages over
    and over, but some testing on current code did not show that happening,
    at least with the test described in that commit.

    So add back the behaviour, as at the very least it is a nice to have
    optimization.

    Fixes: 7b508037d4cac3 ("btrfs: defrag: use defrag_one_cluster() to implement btrfs_defrag_file()")
    CC: stable@vger.kernel.org # 5.16
    Signed-off-by: Filipe Manana <fdmanana@suse.com>
    Signed-off-by: David Sterba <dsterba@suse.com>
    Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
    ---
    fs/btrfs/ioctl.c | 9 +++++++++
    1 file changed, 9 insertions(+)

    --- a/fs/btrfs/ioctl.c
    +++ b/fs/btrfs/ioctl.c
    @@ -1511,6 +1511,7 @@ int btrfs_defrag_file(struct inode *inod
    int compress_type = BTRFS_COMPRESS_ZLIB;
    int ret = 0;
    u32 extent_thresh = range->extent_thresh;
    + pgoff_t start_index;

    if (isize == 0)
    return 0;
    @@ -1552,6 +1553,14 @@ int btrfs_defrag_file(struct inode *inod
    file_ra_state_init(ra, inode->i_mapping);
    }

    + /*
    + * Make writeback start from the beginning of the range, so that the
    + * defrag range can be written sequentially.
    + */
    + start_index = cur >> PAGE_SHIFT;
    + if (start_index < inode->i_mapping->writeback_index)
    + inode->i_mapping->writeback_index = start_index;
    +
    while (cur < last_byte) {
    const unsigned long prev_sectors_defragged = sectors_defragged;
    u64 cluster_end;

    \
     
     \ /
      Last update: 2022-01-31 12:41    [W:2.945 / U:0.504 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site