+ info = inode->i_pipe;
+
+ if (!PIPE_READERS(*inode)) {
+ send_sig(SIGPIPE, current, 0);
+ ret = -EPIPE;
+ goto out;
+ }
+
+ /* We try to merge small writes */
+ if (info->nrbufs && total_len < PAGE_SIZE) {
+ int lastbuf = (info->curbuf + info->nrbufs - 1) & (PIPE_BUFFERS-1);
+ struct pipe_buffer *buf = info->bufs + lastbuf;
+ struct pipe_buf_operations *ops = buf->ops;
+ int offset = buf->offset + buf->len;
+ if (ops->can_merge && offset + total_len <= PAGE_SIZE) {
+ void *addr = ops->map(filp, info, buf);
+ int error = pipe_iov_copy_from_user(offset + addr, iov, total_len);
+ ops->unmap(info, buf);
+ ret = error;
+ do_wakeup = 1;
+ if (error)
+ goto out;
+ buf->len += total_len;
+ ret = total_len;
+ goto out;
+ }
+
+ }
+