lkml.org 
[lkml]   [2016]   [Mar]   [1]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH 4.4 069/342] bcache: Change refill_dirty() to always scan entire disk if necessary
    Date
    4.4-stable review patch.  If anyone has any objections, please let me know.

    ------------------

    From: Kent Overstreet <kent.overstreet@gmail.com>

    commit 627ccd20b4ad3ba836472468208e2ac4dfadbf03 upstream.

    Previously, it would only scan the entire disk if it was starting from
    the very start of the disk - i.e. if the previous scan got to the end.

    This was broken by refill_full_stripes(), which updates last_scanned so
    that refill_dirty was never triggering the searched_from_start path.

    But if we change refill_dirty() to always scan the entire disk if
    necessary, regardless of what last_scanned was, the code gets cleaner
    and we fix that bug too.

    Signed-off-by: Kent Overstreet <kent.overstreet@gmail.com>
    Signed-off-by: Jens Axboe <axboe@fb.com>
    Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>

    ---
    drivers/md/bcache/writeback.c | 37 ++++++++++++++++++++++++++++++-------
    1 file changed, 30 insertions(+), 7 deletions(-)

    --- a/drivers/md/bcache/writeback.c
    +++ b/drivers/md/bcache/writeback.c
    @@ -323,6 +323,10 @@ void bcache_dev_sectors_dirty_add(struct

    static bool dirty_pred(struct keybuf *buf, struct bkey *k)
    {
    + struct cached_dev *dc = container_of(buf, struct cached_dev, writeback_keys);
    +
    + BUG_ON(KEY_INODE(k) != dc->disk.id);
    +
    return KEY_DIRTY(k);
    }

    @@ -372,11 +376,24 @@ next:
    }
    }

    +/*
    + * Returns true if we scanned the entire disk
    + */
    static bool refill_dirty(struct cached_dev *dc)
    {
    struct keybuf *buf = &dc->writeback_keys;
    + struct bkey start = KEY(dc->disk.id, 0, 0);
    struct bkey end = KEY(dc->disk.id, MAX_KEY_OFFSET, 0);
    - bool searched_from_start = false;
    + struct bkey start_pos;
    +
    + /*
    + * make sure keybuf pos is inside the range for this disk - at bringup
    + * we might not be attached yet so this disk's inode nr isn't
    + * initialized then
    + */
    + if (bkey_cmp(&buf->last_scanned, &start) < 0 ||
    + bkey_cmp(&buf->last_scanned, &end) > 0)
    + buf->last_scanned = start;

    if (dc->partial_stripes_expensive) {
    refill_full_stripes(dc);
    @@ -384,14 +401,20 @@ static bool refill_dirty(struct cached_d
    return false;
    }

    - if (bkey_cmp(&buf->last_scanned, &end) >= 0) {
    - buf->last_scanned = KEY(dc->disk.id, 0, 0);
    - searched_from_start = true;
    - }
    -
    + start_pos = buf->last_scanned;
    bch_refill_keybuf(dc->disk.c, buf, &end, dirty_pred);

    - return bkey_cmp(&buf->last_scanned, &end) >= 0 && searched_from_start;
    + if (bkey_cmp(&buf->last_scanned, &end) < 0)
    + return false;
    +
    + /*
    + * If we get to the end start scanning again from the beginning, and
    + * only scan up to where we initially started scanning from:
    + */
    + buf->last_scanned = start;
    + bch_refill_keybuf(dc->disk.c, buf, &start_pos, dirty_pred);
    +
    + return bkey_cmp(&buf->last_scanned, &start_pos) >= 0;
    }

    static int bch_writeback_thread(void *arg)
    \
     
     \ /
      Last update: 2016-03-02 02:41    [W:4.035 / U:0.240 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site