lkml.org 
[lkml]   [2015]   [Nov]   [6]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH 4.1 25/86] mm: make sendfile(2) killable
    Date
    4.1-stable review patch.  If anyone has any objections, please let me know.

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

    From: Jan Kara <jack@suse.com>

    commit 296291cdd1629c308114504b850dc343eabc2782 upstream.

    Currently a simple program below issues a sendfile(2) system call which
    takes about 62 days to complete in my test KVM instance.

    int fd;
    off_t off = 0;

    fd = open("file", O_RDWR | O_TRUNC | O_SYNC | O_CREAT, 0644);
    ftruncate(fd, 2);
    lseek(fd, 0, SEEK_END);
    sendfile(fd, fd, &off, 0xfffffff);

    Now you should not ask kernel to do a stupid stuff like copying 256MB in
    2-byte chunks and call fsync(2) after each chunk but if you do, sysadmin
    should have a way to stop you.

    We actually do have a check for fatal_signal_pending() in
    generic_perform_write() which triggers in this path however because we
    always succeed in writing something before the check is done, we return
    value > 0 from generic_perform_write() and thus the information about
    signal gets lost.

    Fix the problem by doing the signal check before writing anything. That
    way generic_perform_write() returns -EINTR, the error gets propagated up
    and the sendfile loop terminates early.

    Signed-off-by: Jan Kara <jack@suse.com>
    Reported-by: Dmitry Vyukov <dvyukov@google.com>
    Cc: Al Viro <viro@ZenIV.linux.org.uk>
    Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
    Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
    Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>

    ---
    mm/filemap.c | 9 +++++----
    1 file changed, 5 insertions(+), 4 deletions(-)

    --- a/mm/filemap.c
    +++ b/mm/filemap.c
    @@ -2461,6 +2461,11 @@ again:
    break;
    }

    + if (fatal_signal_pending(current)) {
    + status = -EINTR;
    + break;
    + }
    +
    status = a_ops->write_begin(file, mapping, pos, bytes, flags,
    &page, &fsdata);
    if (unlikely(status < 0))
    @@ -2498,10 +2503,6 @@ again:
    written += copied;

    balance_dirty_pages_ratelimited(mapping);
    - if (fatal_signal_pending(current)) {
    - status = -EINTR;
    - break;
    - }
    } while (iov_iter_count(i));

    return written ? written : status;



    \
     
     \ /
      Last update: 2015-11-06 22:01    [W:4.076 / U:0.064 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site