lkml.org 
[lkml]   [2017]   [Aug]   [9]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH 4.12 038/106] ext4: fix SEEK_HOLE/SEEK_DATA for blocksize < pagesize
    Date
    4.12-stable review patch.  If anyone has any objections, please let me know.

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

    From: Jan Kara <jack@suse.cz>

    commit fcf5ea10992fbac3c7473a1db33d56a139333cd1 upstream.

    ext4_find_unwritten_pgoff() does not properly handle a situation when
    starting index is in the middle of a page and blocksize < pagesize. The
    following command shows the bug on filesystem with 1k blocksize:

    xfs_io -f -c "falloc 0 4k" \
    -c "pwrite 1k 1k" \
    -c "pwrite 3k 1k" \
    -c "seek -a -r 0" foo

    In this example, neither lseek(fd, 1024, SEEK_HOLE) nor lseek(fd, 2048,
    SEEK_DATA) will return the correct result.

    Fix the problem by neglecting buffers in a page before starting offset.

    Reported-by: Andreas Gruenbacher <agruenba@redhat.com>
    Signed-off-by: Theodore Ts'o <tytso@mit.edu>
    Signed-off-by: Jan Kara <jack@suse.cz>
    Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>

    ---
    fs/ext4/file.c | 3 +++
    1 file changed, 3 insertions(+)

    --- a/fs/ext4/file.c
    +++ b/fs/ext4/file.c
    @@ -521,6 +521,8 @@ static int ext4_find_unwritten_pgoff(str
    lastoff = page_offset(page);
    bh = head = page_buffers(page);
    do {
    + if (lastoff + bh->b_size <= startoff)
    + goto next;
    if (buffer_uptodate(bh) ||
    buffer_unwritten(bh)) {
    if (whence == SEEK_DATA)
    @@ -535,6 +537,7 @@ static int ext4_find_unwritten_pgoff(str
    unlock_page(page);
    goto out;
    }
    +next:
    lastoff += bh->b_size;
    bh = bh->b_this_page;
    } while (bh != head);

    \
     
     \ /
      Last update: 2017-08-09 19:14    [W:4.800 / U:0.036 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site