lkml.org 
[lkml]   [2020]   [Nov]   [17]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH 5.4 099/151] xfs: fix brainos in the refcount scrubbers rmap fragment processor
    Date
    From: Darrick J. Wong <darrick.wong@oracle.com>

    [ Upstream commit 54e9b09e153842ab5adb8a460b891e11b39e9c3d ]

    Fix some serious WTF in the reference count scrubber's rmap fragment
    processing. The code comment says that this loop is supposed to move
    all fragment records starting at or before bno onto the worklist, but
    there's no obvious reason why nr (the number of items added) should
    increment starting from 1, and breaking the loop when we've added the
    target number seems dubious since we could have more rmap fragments that
    should have been added to the worklist.

    This seems to manifest in xfs/411 when adding one to the refcount field.

    Fixes: dbde19da9637 ("xfs: cross-reference the rmapbt data with the refcountbt")
    Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>
    Reviewed-by: Christoph Hellwig <hch@lst.de>
    Signed-off-by: Sasha Levin <sashal@kernel.org>
    ---
    fs/xfs/scrub/refcount.c | 8 +++-----
    1 file changed, 3 insertions(+), 5 deletions(-)

    diff --git a/fs/xfs/scrub/refcount.c b/fs/xfs/scrub/refcount.c
    index 0cab11a5d3907..5c6b71b75ca10 100644
    --- a/fs/xfs/scrub/refcount.c
    +++ b/fs/xfs/scrub/refcount.c
    @@ -170,7 +170,6 @@ xchk_refcountbt_process_rmap_fragments(
    */
    INIT_LIST_HEAD(&worklist);
    rbno = NULLAGBLOCK;
    - nr = 1;

    /* Make sure the fragments actually /are/ in agbno order. */
    bno = 0;
    @@ -184,15 +183,14 @@ xchk_refcountbt_process_rmap_fragments(
    * Find all the rmaps that start at or before the refc extent,
    * and put them on the worklist.
    */
    + nr = 0;
    list_for_each_entry_safe(frag, n, &refchk->fragments, list) {
    - if (frag->rm.rm_startblock > refchk->bno)
    - goto done;
    + if (frag->rm.rm_startblock > refchk->bno || nr > target_nr)
    + break;
    bno = frag->rm.rm_startblock + frag->rm.rm_blockcount;
    if (bno < rbno)
    rbno = bno;
    list_move_tail(&frag->list, &worklist);
    - if (nr == target_nr)
    - break;
    nr++;
    }

    --
    2.27.0


    \
     
     \ /
      Last update: 2020-11-17 14:29    [W:4.131 / U:0.320 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site