From: David Howells <dhowells@redhat.com>
To: Christoph Hellwig <hch@infradead.org>
Cc: dhowells@redhat.com, Jens Axboe <axboe@kernel.dk>,
Al Viro <viro@zeniv.linux.org.uk>,
Matthew Wilcox <willy@infradead.org>, Jan Kara <jack@suse.cz>,
Jeff Layton <jlayton@kernel.org>,
David Hildenbrand <david@redhat.com>,
Jason Gunthorpe <jgg@nvidia.com>,
Logan Gunthorpe <logang@deltatee.com>,
Hillf Danton <hdanton@sina.com>,
Linus Torvalds <torvalds@linux-foundation.org>,
linux-fsdevel@vger.kernel.org, linux-block@vger.kernel.org,
linux-kernel@vger.kernel.org, linux-mm@kvack.org,
Miklos Szeredi <miklos@szeredi.hu>,
Christoph Hellwig <hch@lst.de>,
John Hubbard <jhubbard@nvidia.com>,
linux-unionfs@vger.kernel.org
Subject: [RFC PATCH] splice: Convert longs and some ints into ssize_t
Date: Wed, 15 Mar 2023 16:34:54 +0000 [thread overview]
Message-ID: <295324.1678898094@warthog.procyon.org.uk> (raw)
In-Reply-To: <ZBCvdKQskS46qyV3@infradead.org>
Christoph Hellwig <hch@infradead.org> wrote:
> The (pre-existing) long here is odd given that ->splice_read
> returns a ssize_t. This might be a good time to fix that up.
Here's a patch to do that. I'm not sure yet that I've got all the places that
need changing as there are a couple of function pointer-taking functions where
the pointed-to function return value should be changed.
There are a couple of potential bugs fixed here too, where something takes a
size_t length, but counts the data spliced in an int. iter_to_pipe() for
example.
David
---
splice: Convert longs and some ints into ssize_t
Convert 'long' and some 'int' into ssize_t in the code involved in splice.
Suggested-by: Christoph Hellwig <hch@lst.de>
Signed-off-by: David Howells <dhowells@redhat.com>
cc: Christoph Hellwig <hch@lst.de>
cc: Jens Axboe <axboe@kernel.dk>
cc: Al Viro <viro@zeniv.linux.org.uk>
cc: John Hubbard <jhubbard@nvidia.com>
cc: David Hildenbrand <david@redhat.com>
cc: Matthew Wilcox <willy@infradead.org>
cc: linux-block@vger.kernel.org
cc: linux-fsdevel@vger.kernel.org
cc: linux-mm@kvack.org
Link: https://lore.kernel.org/r/ZBCvdKQskS46qyV3@infradead.org/
---
drivers/char/mem.c | 4 -
drivers/char/virtio_console.c | 7 +-
fs/splice.c | 119 +++++++++++++++++++++---------------------
include/linux/splice.h | 24 ++++----
4 files changed, 78 insertions(+), 76 deletions(-)
diff --git a/drivers/char/mem.c b/drivers/char/mem.c
index ffb101d349f0..230b72e12c54 100644
--- a/drivers/char/mem.c
+++ b/drivers/char/mem.c
@@ -468,8 +468,8 @@ static ssize_t write_iter_null(struct kiocb *iocb, struct iov_iter *from)
return count;
}
-static int pipe_to_null(struct pipe_inode_info *info, struct pipe_buffer *buf,
- struct splice_desc *sd)
+static ssize_t pipe_to_null(struct pipe_inode_info *info, struct pipe_buffer *buf,
+ struct splice_desc *sd)
{
return sd->len;
}
diff --git a/drivers/char/virtio_console.c b/drivers/char/virtio_console.c
index d5ac4d955bc8..d38bee859d5c 100644
--- a/drivers/char/virtio_console.c
+++ b/drivers/char/virtio_console.c
@@ -854,11 +854,12 @@ struct sg_list {
struct scatterlist *sg;
};
-static int pipe_to_sg(struct pipe_inode_info *pipe, struct pipe_buffer *buf,
- struct splice_desc *sd)
+static ssize_t pipe_to_sg(struct pipe_inode_info *pipe, struct pipe_buffer *buf,
+ struct splice_desc *sd)
{
struct sg_list *sgl = sd->u.data;
- unsigned int offset, len;
+ ssize_t len;
+ size_t offset;
if (sgl->n == sgl->size)
return 0;
diff --git a/fs/splice.c b/fs/splice.c
index f46dd1fb367b..2bfa94d21346 100644
--- a/fs/splice.c
+++ b/fs/splice.c
@@ -186,7 +186,8 @@ ssize_t splice_to_pipe(struct pipe_inode_info *pipe,
unsigned int tail = pipe->tail;
unsigned int head = pipe->head;
unsigned int mask = pipe->ring_size - 1;
- int ret = 0, page_nr = 0;
+ ssize_t ret = 0;
+ int page_nr = 0;
if (!spd_pages)
return 0;
@@ -232,7 +233,7 @@ ssize_t add_to_pipe(struct pipe_inode_info *pipe, struct pipe_buffer *buf)
unsigned int head = pipe->head;
unsigned int tail = pipe->tail;
unsigned int mask = pipe->ring_size - 1;
- int ret;
+ ssize_t ret;
if (unlikely(!pipe->readers)) {
send_sig(SIGPIPE, current, 0);
@@ -414,8 +415,8 @@ EXPORT_SYMBOL(nosteal_pipe_buf_ops);
* Send 'sd->len' bytes to socket from 'sd->file' at position 'sd->pos'
* using sendpage(). Return the number of bytes sent.
*/
-static int pipe_to_sendpage(struct pipe_inode_info *pipe,
- struct pipe_buffer *buf, struct splice_desc *sd)
+static ssize_t pipe_to_sendpage(struct pipe_inode_info *pipe,
+ struct pipe_buffer *buf, struct splice_desc *sd)
{
struct file *file = sd->u.file;
loff_t pos = sd->pos;
@@ -468,7 +469,7 @@ static int splice_from_pipe_feed(struct pipe_inode_info *pipe, struct splice_des
unsigned int head = pipe->head;
unsigned int tail = pipe->tail;
unsigned int mask = pipe->ring_size - 1;
- int ret;
+ ssize_t ret;
while (!pipe_empty(head, tail)) {
struct pipe_buffer *buf = &pipe->bufs[tail & mask];
@@ -621,7 +622,7 @@ static void splice_from_pipe_end(struct pipe_inode_info *pipe, struct splice_des
ssize_t __splice_from_pipe(struct pipe_inode_info *pipe, struct splice_desc *sd,
splice_actor *actor)
{
- int ret;
+ ssize_t ret;
splice_from_pipe_begin(sd);
do {
@@ -827,8 +828,8 @@ static int warn_unsupported(struct file *file, const char *op)
/*
* Attempt to initiate a splice from pipe to file.
*/
-static long do_splice_from(struct pipe_inode_info *pipe, struct file *out,
- loff_t *ppos, size_t len, unsigned int flags)
+static ssize_t do_splice_from(struct pipe_inode_info *pipe, struct file *out,
+ loff_t *ppos, size_t len, unsigned int flags)
{
if (unlikely(!out->f_op->splice_write))
return warn_unsupported(out, "write");
@@ -850,12 +851,12 @@ static long do_splice_from(struct pipe_inode_info *pipe, struct file *out,
* If successful, it returns the amount of data spliced, 0 if it hit the EOF or
* a hole and a negative error code otherwise.
*/
-long vfs_splice_read(struct file *in, loff_t *ppos,
- struct pipe_inode_info *pipe, size_t len,
- unsigned int flags)
+ssize_t vfs_splice_read(struct file *in, loff_t *ppos,
+ struct pipe_inode_info *pipe, size_t len,
+ unsigned int flags)
{
unsigned int p_space;
- int ret;
+ ssize_t ret;
if (unlikely(!(in->f_mode & FMODE_READ)))
return -EBADF;
@@ -894,7 +895,7 @@ ssize_t splice_direct_to_actor(struct file *in, struct splice_desc *sd,
splice_direct_actor *actor)
{
struct pipe_inode_info *pipe;
- long ret, bytes;
+ ssize_t ret, bytes;
size_t len;
int i, flags, more;
@@ -1007,7 +1008,7 @@ ssize_t splice_direct_to_actor(struct file *in, struct splice_desc *sd,
}
EXPORT_SYMBOL(splice_direct_to_actor);
-static int direct_splice_actor(struct pipe_inode_info *pipe,
+static ssize_t direct_splice_actor(struct pipe_inode_info *pipe,
struct splice_desc *sd)
{
struct file *file = sd->u.file;
@@ -1032,8 +1033,8 @@ static int direct_splice_actor(struct pipe_inode_info *pipe,
* can splice directly through a process-private pipe.
*
*/
-long do_splice_direct(struct file *in, loff_t *ppos, struct file *out,
- loff_t *opos, size_t len, unsigned int flags)
+ssize_t do_splice_direct(struct file *in, loff_t *ppos, struct file *out,
+ loff_t *opos, size_t len, unsigned int flags)
{
struct splice_desc sd = {
.len = len,
@@ -1043,7 +1044,7 @@ long do_splice_direct(struct file *in, loff_t *ppos, struct file *out,
.u.file = out,
.opos = opos,
};
- long ret;
+ ssize_t ret;
if (unlikely(!(out->f_mode & FMODE_WRITE)))
return -EBADF;
@@ -1080,16 +1081,16 @@ static int wait_for_space(struct pipe_inode_info *pipe, unsigned flags)
}
}
-static int splice_pipe_to_pipe(struct pipe_inode_info *ipipe,
- struct pipe_inode_info *opipe,
- size_t len, unsigned int flags);
+static ssize_t splice_pipe_to_pipe(struct pipe_inode_info *ipipe,
+ struct pipe_inode_info *opipe,
+ size_t len, unsigned int flags);
-long splice_file_to_pipe(struct file *in,
- struct pipe_inode_info *opipe,
- loff_t *offset,
- size_t len, unsigned int flags)
+ssize_t splice_file_to_pipe(struct file *in,
+ struct pipe_inode_info *opipe,
+ loff_t *offset,
+ size_t len, unsigned int flags)
{
- long ret;
+ ssize_t ret;
pipe_lock(opipe);
ret = wait_for_space(opipe, flags);
@@ -1104,13 +1105,13 @@ long splice_file_to_pipe(struct file *in,
/*
* Determine where to splice to/from.
*/
-long do_splice(struct file *in, loff_t *off_in, struct file *out,
- loff_t *off_out, size_t len, unsigned int flags)
+ssize_t do_splice(struct file *in, loff_t *off_in, struct file *out,
+ loff_t *off_out, size_t len, unsigned int flags)
{
struct pipe_inode_info *ipipe;
struct pipe_inode_info *opipe;
loff_t offset;
- long ret;
+ ssize_t ret;
if (unlikely(!(in->f_mode & FMODE_READ) ||
!(out->f_mode & FMODE_WRITE)))
@@ -1192,14 +1193,14 @@ long do_splice(struct file *in, loff_t *off_in, struct file *out,
return -EINVAL;
}
-static long __do_splice(struct file *in, loff_t __user *off_in,
- struct file *out, loff_t __user *off_out,
- size_t len, unsigned int flags)
+static ssize_t __do_splice(struct file *in, loff_t __user *off_in,
+ struct file *out, loff_t __user *off_out,
+ size_t len, unsigned int flags)
{
struct pipe_inode_info *ipipe;
struct pipe_inode_info *opipe;
loff_t offset, *__off_in = NULL, *__off_out = NULL;
- long ret;
+ ssize_t ret;
ipipe = get_pipe_info(in, true);
opipe = get_pipe_info(out, true);
@@ -1232,16 +1233,16 @@ static long __do_splice(struct file *in, loff_t __user *off_in,
return ret;
}
-static int iter_to_pipe(struct iov_iter *from,
- struct pipe_inode_info *pipe,
- unsigned flags)
+static ssize_t iter_to_pipe(struct iov_iter *from,
+ struct pipe_inode_info *pipe,
+ unsigned flags)
{
struct pipe_buffer buf = {
.ops = &user_page_pipe_buf_ops,
.flags = flags
};
size_t total = 0;
- int ret = 0;
+ ssize_t ret = 0;
while (iov_iter_count(from)) {
struct page *pages[16];
@@ -1257,7 +1258,7 @@ static int iter_to_pipe(struct iov_iter *from,
n = DIV_ROUND_UP(left + start, PAGE_SIZE);
for (i = 0; i < n; i++) {
- int size = min_t(int, left, PAGE_SIZE - start);
+ size_t size = min_t(int, left, PAGE_SIZE - start);
buf.page = pages[i];
buf.offset = start;
@@ -1279,10 +1280,10 @@ static int iter_to_pipe(struct iov_iter *from,
return total ? total : ret;
}
-static int pipe_to_user(struct pipe_inode_info *pipe, struct pipe_buffer *buf,
- struct splice_desc *sd)
+static ssize_t pipe_to_user(struct pipe_inode_info *pipe, struct pipe_buffer *buf,
+ struct splice_desc *sd)
{
- int n = copy_page_to_iter(buf->page, buf->offset, sd->len, sd->u.data);
+ size_t n = copy_page_to_iter(buf->page, buf->offset, sd->len, sd->u.data);
return n == sd->len ? n : -EFAULT;
}
@@ -1290,8 +1291,8 @@ static int pipe_to_user(struct pipe_inode_info *pipe, struct pipe_buffer *buf,
* For lack of a better implementation, implement vmsplice() to userspace
* as a simple copy of the pipes pages to the user iov.
*/
-static long vmsplice_to_user(struct file *file, struct iov_iter *iter,
- unsigned int flags)
+static ssize_t vmsplice_to_user(struct file *file, struct iov_iter *iter,
+ unsigned int flags)
{
struct pipe_inode_info *pipe = get_pipe_info(file, true);
struct splice_desc sd = {
@@ -1299,7 +1300,7 @@ static long vmsplice_to_user(struct file *file, struct iov_iter *iter,
.flags = flags,
.u.data = iter
};
- long ret = 0;
+ ssize_t ret = 0;
if (!pipe)
return -EBADF;
@@ -1318,12 +1319,12 @@ static long vmsplice_to_user(struct file *file, struct iov_iter *iter,
* as splice-from-memory, where the regular splice is splice-from-file (or
* to file). In both cases the output is a pipe, naturally.
*/
-static long vmsplice_to_pipe(struct file *file, struct iov_iter *iter,
- unsigned int flags)
+static ssize_t vmsplice_to_pipe(struct file *file, struct iov_iter *iter,
+ unsigned int flags)
{
struct pipe_inode_info *pipe;
- long ret = 0;
- unsigned buf_flag = 0;
+ ssize_t ret = 0;
+ unsigned int buf_flag = 0;
if (flags & SPLICE_F_GIFT)
buf_flag = PIPE_BUF_FLAG_GIFT;
@@ -1414,7 +1415,7 @@ SYSCALL_DEFINE6(splice, int, fd_in, loff_t __user *, off_in,
size_t, len, unsigned int, flags)
{
struct fd in, out;
- long error;
+ ssize_t error;
if (unlikely(!len))
return 0;
@@ -1514,15 +1515,15 @@ static int opipe_prep(struct pipe_inode_info *pipe, unsigned int flags)
/*
* Splice contents of ipipe to opipe.
*/
-static int splice_pipe_to_pipe(struct pipe_inode_info *ipipe,
- struct pipe_inode_info *opipe,
- size_t len, unsigned int flags)
+static ssize_t splice_pipe_to_pipe(struct pipe_inode_info *ipipe,
+ struct pipe_inode_info *opipe,
+ size_t len, unsigned int flags)
{
struct pipe_buffer *ibuf, *obuf;
unsigned int i_head, o_head;
unsigned int i_tail, o_tail;
unsigned int i_mask, o_mask;
- int ret = 0;
+ ssize_t ret = 0;
bool input_wakeup = false;
@@ -1651,15 +1652,15 @@ static int splice_pipe_to_pipe(struct pipe_inode_info *ipipe,
/*
* Link contents of ipipe to opipe.
*/
-static int link_pipe(struct pipe_inode_info *ipipe,
- struct pipe_inode_info *opipe,
- size_t len, unsigned int flags)
+static ssize_t link_pipe(struct pipe_inode_info *ipipe,
+ struct pipe_inode_info *opipe,
+ size_t len, unsigned int flags)
{
struct pipe_buffer *ibuf, *obuf;
unsigned int i_head, o_head;
unsigned int i_tail, o_tail;
unsigned int i_mask, o_mask;
- int ret = 0;
+ ssize_t ret = 0;
/*
* Potential ABBA deadlock, work around it by ordering lock
@@ -1742,11 +1743,11 @@ static int link_pipe(struct pipe_inode_info *ipipe,
* The 'flags' used are the SPLICE_F_* variants, currently the only
* applicable one is SPLICE_F_NONBLOCK.
*/
-long do_tee(struct file *in, struct file *out, size_t len, unsigned int flags)
+ssize_t do_tee(struct file *in, struct file *out, size_t len, unsigned int flags)
{
struct pipe_inode_info *ipipe = get_pipe_info(in, true);
struct pipe_inode_info *opipe = get_pipe_info(out, true);
- int ret = -EINVAL;
+ ssize_t ret = -EINVAL;
if (unlikely(!(in->f_mode & FMODE_READ) ||
!(out->f_mode & FMODE_WRITE)))
@@ -1778,7 +1779,7 @@ long do_tee(struct file *in, struct file *out, size_t len, unsigned int flags)
SYSCALL_DEFINE4(tee, int, fdin, int, fdout, size_t, len, unsigned int, flags)
{
struct fd in, out;
- int error;
+ ssize_t error;
if (unlikely(flags & ~SPLICE_F_ALL))
return -EINVAL;
diff --git a/include/linux/splice.h b/include/linux/splice.h
index 8f052c3dae95..6af5e197ccd0 100644
--- a/include/linux/splice.h
+++ b/include/linux/splice.h
@@ -62,10 +62,10 @@ struct splice_pipe_desc {
void (*spd_release)(struct splice_pipe_desc *, unsigned int);
};
-typedef int (splice_actor)(struct pipe_inode_info *, struct pipe_buffer *,
- struct splice_desc *);
-typedef int (splice_direct_actor)(struct pipe_inode_info *,
- struct splice_desc *);
+typedef ssize_t (splice_actor)(struct pipe_inode_info *, struct pipe_buffer *,
+ struct splice_desc *);
+typedef ssize_t (splice_direct_actor)(struct pipe_inode_info *,
+ struct splice_desc *);
extern ssize_t splice_from_pipe(struct pipe_inode_info *, struct file *,
loff_t *, size_t, unsigned int,
@@ -76,17 +76,17 @@ extern ssize_t splice_to_pipe(struct pipe_inode_info *,
struct splice_pipe_desc *);
extern ssize_t add_to_pipe(struct pipe_inode_info *,
struct pipe_buffer *);
-long vfs_splice_read(struct file *in, loff_t *ppos,
- struct pipe_inode_info *pipe, size_t len,
- unsigned int flags);
+ssize_t vfs_splice_read(struct file *in, loff_t *ppos,
+ struct pipe_inode_info *pipe, size_t len,
+ unsigned int flags);
extern ssize_t splice_direct_to_actor(struct file *, struct splice_desc *,
splice_direct_actor *);
-extern long do_splice(struct file *in, loff_t *off_in,
- struct file *out, loff_t *off_out,
- size_t len, unsigned int flags);
+extern ssize_t do_splice(struct file *in, loff_t *off_in,
+ struct file *out, loff_t *off_out,
+ size_t len, unsigned int flags);
-extern long do_tee(struct file *in, struct file *out, size_t len,
- unsigned int flags);
+extern ssize_t do_tee(struct file *in, struct file *out, size_t len,
+ unsigned int flags);
/*
* for dynamic pipe sizing
next prev parent reply other threads:[~2023-03-15 16:35 UTC|newest]
Thread overview: 33+ messages / expand[flat|nested] mbox.gz Atom feed top
2023-03-08 16:52 [PATCH v17 00/14] splice, block: Use page pinning and kill ITER_PIPE David Howells
2023-03-08 16:52 ` [PATCH v17 01/14] splice: Clean up direct_splice_read() a bit David Howells
2023-03-14 17:30 ` Christoph Hellwig
2023-03-08 16:52 ` [PATCH v17 02/14] splice: Make do_splice_to() generic and export it David Howells
2023-03-14 17:31 ` Christoph Hellwig
2023-03-14 21:15 ` David Howells
2023-03-15 16:34 ` David Howells [this message]
2023-03-08 16:52 ` [PATCH v17 03/14] shmem: Implement splice-read David Howells
2023-03-08 22:39 ` Linus Torvalds
2023-03-14 16:42 ` Matthew Wilcox
2023-03-14 18:02 ` Linus Torvalds
2023-03-14 20:08 ` Matthew Wilcox
2023-03-14 18:26 ` David Howells
2023-03-14 19:07 ` Linus Torvalds
2023-03-14 19:09 ` Linus Torvalds
2023-03-14 21:50 ` David Howells
2023-03-08 23:42 ` David Howells
2023-03-08 16:52 ` [PATCH v17 04/14] overlayfs: " David Howells
2023-03-08 16:52 ` [PATCH v17 05/14] coda: " David Howells
2023-03-13 13:28 ` Jan Harkes
2023-03-08 16:52 ` [PATCH v17 06/14] tty, proc, kernfs, random: Use direct_splice_read() David Howells
2023-03-08 16:52 ` [PATCH v17 07/14] splice: Do splice read from a file without using ITER_PIPE David Howells
2023-03-14 17:32 ` Christoph Hellwig
2023-03-14 21:52 ` David Howells
2023-03-08 16:52 ` [PATCH v17 08/14] iov_iter: Kill ITER_PIPE David Howells
2023-03-08 16:52 ` [PATCH v17 09/14] iomap: Don't get an reference on ZERO_PAGE for direct I/O block zeroing David Howells
2023-03-08 21:08 ` Dave Chinner
2023-03-14 17:33 ` Christoph Hellwig
2023-03-08 16:52 ` [PATCH v17 10/14] block: Fix bio_flagged() so that gcc can better optimise it David Howells
2023-03-08 16:52 ` [PATCH v17 11/14] block: Replace BIO_NO_PAGE_REF with BIO_PAGE_REFFED with inverted logic David Howells
2023-03-08 16:52 ` [PATCH v17 12/14] block: Add BIO_PAGE_PINNED and associated infrastructure David Howells
2023-03-08 16:52 ` [PATCH v17 13/14] block: Convert bio_iov_iter_get_pages to use iov_iter_extract_pages David Howells
2023-03-08 16:52 ` [PATCH v17 14/14] block: convert bio_map_user_iov " David Howells
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=295324.1678898094@warthog.procyon.org.uk \
--to=dhowells@redhat.com \
--cc=axboe@kernel.dk \
--cc=david@redhat.com \
--cc=hch@infradead.org \
--cc=hch@lst.de \
--cc=hdanton@sina.com \
--cc=jack@suse.cz \
--cc=jgg@nvidia.com \
--cc=jhubbard@nvidia.com \
--cc=jlayton@kernel.org \
--cc=linux-block@vger.kernel.org \
--cc=linux-fsdevel@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-mm@kvack.org \
--cc=linux-unionfs@vger.kernel.org \
--cc=logang@deltatee.com \
--cc=miklos@szeredi.hu \
--cc=torvalds@linux-foundation.org \
--cc=viro@zeniv.linux.org.uk \
--cc=willy@infradead.org \
/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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox