splice: teach splice pipe reading about empty pipe buffers
[sfrench/cifs-2.6.git] / fs / splice.c
index c3d00dfc7344648be62ac41244b0708ec72148f6..ce75aec5227441cd028b48b2b177ec73a5d173ac 100644 (file)
@@ -526,6 +526,22 @@ static int splice_from_pipe_feed(struct pipe_inode_info *pipe, struct splice_des
        return 1;
 }
 
+/* We know we have a pipe buffer, but maybe it's empty? */
+static inline bool eat_empty_buffer(struct pipe_inode_info *pipe)
+{
+       unsigned int tail = pipe->tail;
+       unsigned int mask = pipe->ring_size - 1;
+       struct pipe_buffer *buf = &pipe->bufs[tail & mask];
+
+       if (unlikely(!buf->len)) {
+               pipe_buf_release(pipe, buf);
+               pipe->tail = tail+1;
+               return true;
+       }
+
+       return false;
+}
+
 /**
  * splice_from_pipe_next - wait for some data to splice from
  * @pipe:      pipe to splice from
@@ -545,6 +561,7 @@ static int splice_from_pipe_next(struct pipe_inode_info *pipe, struct splice_des
        if (signal_pending(current))
                return -ERESTARTSYS;
 
+repeat:
        while (pipe_empty(pipe->head, pipe->tail)) {
                if (!pipe->writers)
                        return 0;
@@ -566,6 +583,9 @@ static int splice_from_pipe_next(struct pipe_inode_info *pipe, struct splice_des
                pipe_wait_readable(pipe);
        }
 
+       if (eat_empty_buffer(pipe))
+               goto repeat;
+
        return 1;
 }