pipe: merge anon_pipe_buf*_ops
authorChristoph Hellwig <hch@lst.de>
Wed, 20 May 2020 15:58:12 +0000 (17:58 +0200)
committerAl Viro <viro@zeniv.linux.org.uk>
Wed, 20 May 2020 16:11:26 +0000 (12:11 -0400)
All the op vectors are exactly the same, they are just used to encode
packet or nomerge behavior.  There already is a flag for the packet
behavior, so just add a new one to allow for merging.  Inverting it vs
the previous nomerge special casing actually allows for much nicer code.

Signed-off-by: Christoph Hellwig <hch@lst.de>
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
fs/pipe.c
fs/splice.c
include/linux/pipe_fs_i.h

index 16fb72e..8e52b78 100644 (file)
--- a/fs/pipe.c
+++ b/fs/pipe.c
@@ -231,7 +231,6 @@ void generic_pipe_buf_release(struct pipe_inode_info *pipe,
 }
 EXPORT_SYMBOL(generic_pipe_buf_release);
 
-/* New data written to a pipe may be appended to a buffer with this type. */
 static const struct pipe_buf_operations anon_pipe_buf_ops = {
        .confirm = generic_pipe_buf_confirm,
        .release = anon_pipe_buf_release,
@@ -239,40 +238,6 @@ static const struct pipe_buf_operations anon_pipe_buf_ops = {
        .get = generic_pipe_buf_get,
 };
 
-static const struct pipe_buf_operations anon_pipe_buf_nomerge_ops = {
-       .confirm = generic_pipe_buf_confirm,
-       .release = anon_pipe_buf_release,
-       .steal = anon_pipe_buf_steal,
-       .get = generic_pipe_buf_get,
-};
-
-static const struct pipe_buf_operations packet_pipe_buf_ops = {
-       .confirm = generic_pipe_buf_confirm,
-       .release = anon_pipe_buf_release,
-       .steal = anon_pipe_buf_steal,
-       .get = generic_pipe_buf_get,
-};
-
-/**
- * pipe_buf_mark_unmergeable - mark a &struct pipe_buffer as unmergeable
- * @buf:       the buffer to mark
- *
- * Description:
- *     This function ensures that no future writes will be merged into the
- *     given &struct pipe_buffer. This is necessary when multiple pipe buffers
- *     share the same backing page.
- */
-void pipe_buf_mark_unmergeable(struct pipe_buffer *buf)
-{
-       if (buf->ops == &anon_pipe_buf_ops)
-               buf->ops = &anon_pipe_buf_nomerge_ops;
-}
-
-static bool pipe_buf_can_merge(struct pipe_buffer *buf)
-{
-       return buf->ops == &anon_pipe_buf_ops;
-}
-
 /* Done while waiting without holding the pipe lock - thus the READ_ONCE() */
 static inline bool pipe_readable(const struct pipe_inode_info *pipe)
 {
@@ -478,7 +443,8 @@ pipe_write(struct kiocb *iocb, struct iov_iter *from)
                struct pipe_buffer *buf = &pipe->bufs[(head - 1) & mask];
                int offset = buf->offset + buf->len;
 
-               if (pipe_buf_can_merge(buf) && offset + chars <= PAGE_SIZE) {
+               if ((buf->flags & PIPE_BUF_FLAG_CAN_MERGE) &&
+                   offset + chars <= PAGE_SIZE) {
                        ret = pipe_buf_confirm(pipe, buf);
                        if (ret)
                                goto out;
@@ -541,11 +507,10 @@ pipe_write(struct kiocb *iocb, struct iov_iter *from)
                        buf->ops = &anon_pipe_buf_ops;
                        buf->offset = 0;
                        buf->len = 0;
-                       buf->flags = 0;
-                       if (is_packetized(filp)) {
-                               buf->ops = &packet_pipe_buf_ops;
+                       if (is_packetized(filp))
                                buf->flags = PIPE_BUF_FLAG_PACKET;
-                       }
+                       else
+                               buf->flags = PIPE_BUF_FLAG_CAN_MERGE;
                        pipe->tmp_page = NULL;
 
                        copied = copy_page_from_iter(page, 0, PAGE_SIZE, from);
index 88942bf..fb9670e 100644 (file)
@@ -1624,12 +1624,11 @@ retry:
                        *obuf = *ibuf;
 
                        /*
-                        * Don't inherit the gift flag, we need to
+                        * Don't inherit the gift and merge flags, we need to
                         * prevent multiple steals of this page.
                         */
                        obuf->flags &= ~PIPE_BUF_FLAG_GIFT;
-
-                       pipe_buf_mark_unmergeable(obuf);
+                       obuf->flags &= ~PIPE_BUF_FLAG_CAN_MERGE;
 
                        obuf->len = len;
                        ibuf->offset += len;
@@ -1717,12 +1716,11 @@ static int link_pipe(struct pipe_inode_info *ipipe,
                *obuf = *ibuf;
 
                /*
-                * Don't inherit the gift flag, we need to
-                * prevent multiple steals of this page.
+                * Don't inherit the gift and merge flag, we need to prevent
+                * multiple steals of this page.
                 */
                obuf->flags &= ~PIPE_BUF_FLAG_GIFT;
-
-               pipe_buf_mark_unmergeable(obuf);
+               obuf->flags &= ~PIPE_BUF_FLAG_CAN_MERGE;
 
                if (obuf->len > len)
                        obuf->len = len;
index ae58fad..3f7b07b 100644 (file)
@@ -8,6 +8,7 @@
 #define PIPE_BUF_FLAG_ATOMIC   0x02    /* was atomically mapped */
 #define PIPE_BUF_FLAG_GIFT     0x04    /* page is a gift */
 #define PIPE_BUF_FLAG_PACKET   0x08    /* read() as a packet */
+#define PIPE_BUF_FLAG_CAN_MERGE        0x10    /* can merge buffers */
 
 /**
  *     struct pipe_buffer - a linux kernel pipe buffer
@@ -233,7 +234,6 @@ int generic_pipe_buf_confirm(struct pipe_inode_info *, struct pipe_buffer *);
 int generic_pipe_buf_steal(struct pipe_inode_info *, struct pipe_buffer *);
 int generic_pipe_buf_nosteal(struct pipe_inode_info *, struct pipe_buffer *);
 void generic_pipe_buf_release(struct pipe_inode_info *, struct pipe_buffer *);
-void pipe_buf_mark_unmergeable(struct pipe_buffer *buf);
 
 extern const struct pipe_buf_operations nosteal_pipe_buf_ops;