And... I know, I know you already hate me ;) but if you have time, could you check if this patch (with or without the previous debugging patch) makes any difference? Just to be sure. Oleg. --- diff --git a/fs/pipe.c b/fs/pipe.c index 4336b8cccf84..524b8845523e 100644 --- a/fs/pipe.c +++ b/fs/pipe.c @@ -445,7 +445,7 @@ anon_pipe_write(struct kiocb *iocb, struct iov_iter *from) return 0; mutex_lock(&pipe->mutex); - +again: if (!pipe->readers) { send_sig(SIGPIPE, current, 0); ret = -EPIPE; @@ -467,20 +467,24 @@ anon_pipe_write(struct kiocb *iocb, struct iov_iter *from) unsigned int mask = pipe->ring_size - 1; struct pipe_buffer *buf = &pipe->bufs[(head - 1) & mask]; int offset = buf->offset + buf->len; + int xxx; if ((buf->flags & PIPE_BUF_FLAG_CAN_MERGE) && offset + chars <= PAGE_SIZE) { - ret = pipe_buf_confirm(pipe, buf); - if (ret) + xxx = pipe_buf_confirm(pipe, buf); + if (xxx) { + if (!ret) ret = xxx; goto out; + } - ret = copy_page_from_iter(buf->page, offset, chars, from); - if (unlikely(ret < chars)) { - ret = -EFAULT; + xxx = copy_page_from_iter(buf->page, offset, chars, from); + if (unlikely(xxx < chars)) { + if (!ret) ret = -EFAULT; goto out; } - buf->len += ret; + ret += xxx; + buf->len += xxx; if (!iov_iter_count(from)) goto out; } @@ -567,6 +571,7 @@ atomic_inc(&WR_SLEEP); mutex_lock(&pipe->mutex); was_empty = pipe_empty(pipe->head, pipe->tail); wake_next_writer = true; + goto again; } out: if (pipe_full(pipe->head, pipe->tail, pipe->max_usage))