From: Max Kellermann <max.kellermann@gmail.com>
To: viro@zeniv.linux.org.uk, linux-fsdevel@vger.kernel.org,
linux-kernel@vger.kernel.org
Cc: Max Kellermann <max.kellermann@gmail.com>
Subject: [PATCH 4/4] pipe_fs_i.h: add pipe_buf_init()
Date: Fri, 25 Feb 2022 19:54:31 +0100 [thread overview]
Message-ID: <20220225185431.2617232-4-max.kellermann@gmail.com> (raw)
In-Reply-To: <20220225185431.2617232-1-max.kellermann@gmail.com>
Adds one central function which shall be used to initialize a newly
allocated struct pipe_buffer. This shall make the pipe code more
robust for the next time the pipe_buffer struct gets modified, to
avoid leaving new members uninitialized. Instead, adding new members
should also add a new pipe_buf_init() parameter, which causes
compile-time errors in call sites that were not adapted.
This commit doesn't refactor fs/fuse/dev.c because this code looks
obscure to me; it initializes pipe_buffers incrementally through a
variety of functions, too complicated for me to understand.
To: Alexander Viro <viro@zeniv.linux.org.uk>
To: linux-fsdevel@vger.kernel.org
To: linux-kernel@vger.kernel.org
Signed-off-by: Max Kellermann <max.kellermann@gmail.com>
---
fs/pipe.c | 11 +++--------
fs/splice.c | 9 ++++-----
include/linux/pipe_fs_i.h | 20 ++++++++++++++++++++
kernel/watch_queue.c | 8 +++-----
lib/iov_iter.c | 13 +++----------
5 files changed, 33 insertions(+), 28 deletions(-)
diff --git a/fs/pipe.c b/fs/pipe.c
index b2075ecd4751..6da11ea9da49 100644
--- a/fs/pipe.c
+++ b/fs/pipe.c
@@ -518,14 +518,9 @@ pipe_write(struct kiocb *iocb, struct iov_iter *from)
/* Insert it into the buffer array */
buf = &pipe->bufs[head & mask];
- buf->page = page;
- buf->ops = &anon_pipe_buf_ops;
- buf->offset = 0;
- buf->len = 0;
- if (is_packetized(filp))
- buf->flags = PIPE_BUF_FLAG_PACKET;
- else
- buf->flags = PIPE_BUF_FLAG_CAN_MERGE;
+ pipe_buf_init(buf, page, 0, 0,
+ &anon_pipe_buf_ops,
+ is_packetized(filp) ? PIPE_BUF_FLAG_PACKET : PIPE_BUF_FLAG_CAN_MERGE);
pipe->tmp_page = NULL;
copied = copy_page_from_iter(page, 0, PAGE_SIZE, from);
diff --git a/fs/splice.c b/fs/splice.c
index 5dbce4dcc1a7..d2e4205acc46 100644
--- a/fs/splice.c
+++ b/fs/splice.c
@@ -200,12 +200,11 @@ ssize_t splice_to_pipe(struct pipe_inode_info *pipe,
while (!pipe_full(head, tail, pipe->max_usage)) {
struct pipe_buffer *buf = &pipe->bufs[head & mask];
- buf->page = spd->pages[page_nr];
- buf->offset = spd->partial[page_nr].offset;
- buf->len = spd->partial[page_nr].len;
+ pipe_buf_init(buf, spd->pages[page_nr],
+ spd->partial[page_nr].offset,
+ spd->partial[page_nr].len,
+ spd->ops, 0);
buf->private = spd->partial[page_nr].private;
- buf->ops = spd->ops;
- buf->flags = 0;
head++;
pipe->head = head;
diff --git a/include/linux/pipe_fs_i.h b/include/linux/pipe_fs_i.h
index 0e36a58adf0e..61639682cc4e 100644
--- a/include/linux/pipe_fs_i.h
+++ b/include/linux/pipe_fs_i.h
@@ -179,6 +179,26 @@ static inline unsigned int pipe_space_for_user(unsigned int head, unsigned int t
return p_space;
}
+/**
+ * Initialize a struct pipe_buffer.
+ */
+static inline void pipe_buf_init(struct pipe_buffer *buf,
+ struct page *page,
+ unsigned int offset, unsigned int len,
+ const struct pipe_buf_operations *ops,
+ unsigned int flags)
+{
+ buf->page = page;
+ buf->offset = offset;
+ buf->len = len;
+ buf->ops = ops;
+ buf->flags = flags;
+
+ /* not initializing the "private" member because it is only
+ used by pipe_buf_operations which inject it via struct
+ partial_page / struct splice_pipe_desc */
+}
+
/**
* pipe_buf_get - get a reference to a pipe_buffer
* @pipe: the pipe that the buffer belongs to
diff --git a/kernel/watch_queue.c b/kernel/watch_queue.c
index 9c9eb20dd2c5..34720138cc22 100644
--- a/kernel/watch_queue.c
+++ b/kernel/watch_queue.c
@@ -106,12 +106,10 @@ static bool post_one_notification(struct watch_queue *wqueue,
kunmap_atomic(p);
buf = &pipe->bufs[head & mask];
- buf->page = page;
+ pipe_buf_init(buf, page, offset, len,
+ &watch_queue_pipe_buf_ops,
+ PIPE_BUF_FLAG_WHOLE);
buf->private = (unsigned long)wqueue;
- buf->ops = &watch_queue_pipe_buf_ops;
- buf->offset = offset;
- buf->len = len;
- buf->flags = PIPE_BUF_FLAG_WHOLE;
pipe->head = head + 1;
if (!test_and_clear_bit(note, wqueue->notes_bitmap)) {
diff --git a/lib/iov_iter.c b/lib/iov_iter.c
index 6dd5330f7a99..289e96947fb5 100644
--- a/lib/iov_iter.c
+++ b/lib/iov_iter.c
@@ -413,12 +413,8 @@ static size_t copy_page_to_iter_pipe(struct page *page, size_t offset, size_t by
if (pipe_full(i_head, p_tail, pipe->max_usage))
return 0;
- buf->ops = &page_cache_pipe_buf_ops;
- buf->flags = 0;
get_page(page);
- buf->page = page;
- buf->offset = offset;
- buf->len = bytes;
+ pipe_buf_init(buf, page, offset, bytes, &page_cache_pipe_buf_ops, 0);
pipe->head = i_head + 1;
i->iov_offset = offset + bytes;
@@ -577,11 +573,8 @@ static size_t push_pipe(struct iov_iter *i, size_t size,
if (!page)
break;
- buf->ops = &default_pipe_buf_ops;
- buf->flags = 0;
- buf->page = page;
- buf->offset = 0;
- buf->len = min_t(ssize_t, left, PAGE_SIZE);
+ pipe_buf_init(buf, page, 0, min_t(ssize_t, left, PAGE_SIZE),
+ &default_pipe_buf_ops, 0);
left -= buf->len;
iter_head++;
pipe->head = iter_head;
--
2.34.0
next prev parent reply other threads:[~2022-02-25 18:55 UTC|newest]
Thread overview: 10+ messages / expand[flat|nested] mbox.gz Atom feed top
2022-02-25 18:54 [PATCH 1/4] include/pipe_fs_i.h: add missing #includes Max Kellermann
2022-02-25 18:54 ` [PATCH 2/4] fs/pipe: remove duplicate "offset" initializer Max Kellermann
2022-02-25 18:54 ` [PATCH 3/4] fs/pipe: remove unnecessary "buf" initializer Max Kellermann
2022-02-25 18:54 ` Max Kellermann [this message]
2022-03-13 2:37 ` [PATCH 4/4] pipe_fs_i.h: add pipe_buf_init() Al Viro
2022-03-13 2:48 ` Matthew Wilcox
2022-03-13 4:34 ` Al Viro
2022-03-13 6:47 ` Max Kellermann
2022-03-13 1:49 ` [PATCH 1/4] include/pipe_fs_i.h: add missing #includes Al Viro
2022-03-13 6:45 ` Max Kellermann
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20220225185431.2617232-4-max.kellermann@gmail.com \
--to=max.kellermann@gmail.com \
--cc=linux-fsdevel@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=viro@zeniv.linux.org.uk \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.