Skip to content

Commit f6dd975

Browse files
Christoph HellwigAl Viro
authored andcommitted
pipe: merge anon_pipe_buf*_ops
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 <[email protected]> Signed-off-by: Al Viro <[email protected]>
1 parent 00c285d commit f6dd975

File tree

3 files changed

+11
-48
lines changed

3 files changed

+11
-48
lines changed

fs/pipe.c

Lines changed: 5 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -231,48 +231,13 @@ void generic_pipe_buf_release(struct pipe_inode_info *pipe,
231231
}
232232
EXPORT_SYMBOL(generic_pipe_buf_release);
233233

234-
/* New data written to a pipe may be appended to a buffer with this type. */
235234
static const struct pipe_buf_operations anon_pipe_buf_ops = {
236235
.confirm = generic_pipe_buf_confirm,
237236
.release = anon_pipe_buf_release,
238237
.steal = anon_pipe_buf_steal,
239238
.get = generic_pipe_buf_get,
240239
};
241240

242-
static const struct pipe_buf_operations anon_pipe_buf_nomerge_ops = {
243-
.confirm = generic_pipe_buf_confirm,
244-
.release = anon_pipe_buf_release,
245-
.steal = anon_pipe_buf_steal,
246-
.get = generic_pipe_buf_get,
247-
};
248-
249-
static const struct pipe_buf_operations packet_pipe_buf_ops = {
250-
.confirm = generic_pipe_buf_confirm,
251-
.release = anon_pipe_buf_release,
252-
.steal = anon_pipe_buf_steal,
253-
.get = generic_pipe_buf_get,
254-
};
255-
256-
/**
257-
* pipe_buf_mark_unmergeable - mark a &struct pipe_buffer as unmergeable
258-
* @buf: the buffer to mark
259-
*
260-
* Description:
261-
* This function ensures that no future writes will be merged into the
262-
* given &struct pipe_buffer. This is necessary when multiple pipe buffers
263-
* share the same backing page.
264-
*/
265-
void pipe_buf_mark_unmergeable(struct pipe_buffer *buf)
266-
{
267-
if (buf->ops == &anon_pipe_buf_ops)
268-
buf->ops = &anon_pipe_buf_nomerge_ops;
269-
}
270-
271-
static bool pipe_buf_can_merge(struct pipe_buffer *buf)
272-
{
273-
return buf->ops == &anon_pipe_buf_ops;
274-
}
275-
276241
/* Done while waiting without holding the pipe lock - thus the READ_ONCE() */
277242
static inline bool pipe_readable(const struct pipe_inode_info *pipe)
278243
{
@@ -478,7 +443,8 @@ pipe_write(struct kiocb *iocb, struct iov_iter *from)
478443
struct pipe_buffer *buf = &pipe->bufs[(head - 1) & mask];
479444
int offset = buf->offset + buf->len;
480445

481-
if (pipe_buf_can_merge(buf) && offset + chars <= PAGE_SIZE) {
446+
if ((buf->flags & PIPE_BUF_FLAG_CAN_MERGE) &&
447+
offset + chars <= PAGE_SIZE) {
482448
ret = pipe_buf_confirm(pipe, buf);
483449
if (ret)
484450
goto out;
@@ -541,11 +507,10 @@ pipe_write(struct kiocb *iocb, struct iov_iter *from)
541507
buf->ops = &anon_pipe_buf_ops;
542508
buf->offset = 0;
543509
buf->len = 0;
544-
buf->flags = 0;
545-
if (is_packetized(filp)) {
546-
buf->ops = &packet_pipe_buf_ops;
510+
if (is_packetized(filp))
547511
buf->flags = PIPE_BUF_FLAG_PACKET;
548-
}
512+
else
513+
buf->flags = PIPE_BUF_FLAG_CAN_MERGE;
549514
pipe->tmp_page = NULL;
550515

551516
copied = copy_page_from_iter(page, 0, PAGE_SIZE, from);

fs/splice.c

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1624,12 +1624,11 @@ static int splice_pipe_to_pipe(struct pipe_inode_info *ipipe,
16241624
*obuf = *ibuf;
16251625

16261626
/*
1627-
* Don't inherit the gift flag, we need to
1627+
* Don't inherit the gift and merge flags, we need to
16281628
* prevent multiple steals of this page.
16291629
*/
16301630
obuf->flags &= ~PIPE_BUF_FLAG_GIFT;
1631-
1632-
pipe_buf_mark_unmergeable(obuf);
1631+
obuf->flags &= ~PIPE_BUF_FLAG_CAN_MERGE;
16331632

16341633
obuf->len = len;
16351634
ibuf->offset += len;
@@ -1717,12 +1716,11 @@ static int link_pipe(struct pipe_inode_info *ipipe,
17171716
*obuf = *ibuf;
17181717

17191718
/*
1720-
* Don't inherit the gift flag, we need to
1721-
* prevent multiple steals of this page.
1719+
* Don't inherit the gift and merge flag, we need to prevent
1720+
* multiple steals of this page.
17221721
*/
17231722
obuf->flags &= ~PIPE_BUF_FLAG_GIFT;
1724-
1725-
pipe_buf_mark_unmergeable(obuf);
1723+
obuf->flags &= ~PIPE_BUF_FLAG_CAN_MERGE;
17261724

17271725
if (obuf->len > len)
17281726
obuf->len = len;

include/linux/pipe_fs_i.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
#define PIPE_BUF_FLAG_ATOMIC 0x02 /* was atomically mapped */
99
#define PIPE_BUF_FLAG_GIFT 0x04 /* page is a gift */
1010
#define PIPE_BUF_FLAG_PACKET 0x08 /* read() as a packet */
11+
#define PIPE_BUF_FLAG_CAN_MERGE 0x10 /* can merge buffers */
1112

1213
/**
1314
* struct pipe_buffer - a linux kernel pipe buffer
@@ -233,7 +234,6 @@ int generic_pipe_buf_confirm(struct pipe_inode_info *, struct pipe_buffer *);
233234
int generic_pipe_buf_steal(struct pipe_inode_info *, struct pipe_buffer *);
234235
int generic_pipe_buf_nosteal(struct pipe_inode_info *, struct pipe_buffer *);
235236
void generic_pipe_buf_release(struct pipe_inode_info *, struct pipe_buffer *);
236-
void pipe_buf_mark_unmergeable(struct pipe_buffer *buf);
237237

238238
extern const struct pipe_buf_operations nosteal_pipe_buf_ops;
239239

0 commit comments

Comments
 (0)