lkml.org 
[lkml]   [2021]   [Nov]   [29]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH 5.15 056/179] iomap: Fix inline extent handling in iomap_readpage
    Date
    From: Andreas Gruenbacher <agruenba@redhat.com>

    commit d8af404ffce71448f29bbc19a05e3d095baf98eb upstream.

    Before commit 740499c78408 ("iomap: fix the iomap_readpage_actor return
    value for inline data"), when hitting an IOMAP_INLINE extent,
    iomap_readpage_actor would report having read the entire page. Since
    then, it only reports having read the inline data (iomap->length).

    This will force iomap_readpage into another iteration, and the
    filesystem will report an unaligned hole after the IOMAP_INLINE extent.
    But iomap_readpage_actor (now iomap_readpage_iter) isn't prepared to
    deal with unaligned extents, it will get things wrong on filesystems
    with a block size smaller than the page size, and we'll eventually run
    into the following warning in iomap_iter_advance:

    WARN_ON_ONCE(iter->processed > iomap_length(iter));

    Fix that by changing iomap_readpage_iter to return 0 when hitting an
    inline extent; this will cause iomap_iter to stop immediately.

    To fix readahead as well, change iomap_readahead_iter to pass on
    iomap_readpage_iter return values less than or equal to zero.

    Fixes: 740499c78408 ("iomap: fix the iomap_readpage_actor return value for inline data")
    Cc: stable@vger.kernel.org # v5.15+
    Signed-off-by: Andreas Gruenbacher <agruenba@redhat.com>
    Reviewed-by: Christoph Hellwig <hch@lst.de>
    Reviewed-by: Darrick J. Wong <djwong@kernel.org>
    Signed-off-by: Darrick J. Wong <djwong@kernel.org>
    Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
    ---
    fs/iomap/buffered-io.c | 11 +++++++++--
    1 file changed, 9 insertions(+), 2 deletions(-)

    --- a/fs/iomap/buffered-io.c
    +++ b/fs/iomap/buffered-io.c
    @@ -256,8 +256,13 @@ static loff_t iomap_readpage_iter(const
    unsigned poff, plen;
    sector_t sector;

    - if (iomap->type == IOMAP_INLINE)
    - return min(iomap_read_inline_data(iter, page), length);
    + if (iomap->type == IOMAP_INLINE) {
    + loff_t ret = iomap_read_inline_data(iter, page);
    +
    + if (ret < 0)
    + return ret;
    + return 0;
    + }

    /* zero post-eof blocks as the page may be mapped */
    iop = iomap_page_create(iter->inode, page);
    @@ -370,6 +375,8 @@ static loff_t iomap_readahead_iter(const
    ctx->cur_page_in_bio = false;
    }
    ret = iomap_readpage_iter(iter, ctx, done);
    + if (ret <= 0)
    + return ret;
    }

    return done;

    \
     
     \ /
      Last update: 2021-11-29 19:42    [W:5.109 / U:0.220 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site