Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 87e5e6da authored by Jens Axboe's avatar Jens Axboe
Browse files

uio: make import_iovec()/compat_import_iovec() return bytes on success



Currently these functions return < 0 on error, and 0 for success.
Change that so that we return < 0 on error, but number of bytes
for success.

Some callers already treat the return value that way, others need a
slight tweak.

Signed-off-by: default avatarJens Axboe <axboe@kernel.dk>
parent 61939b12
Loading
Loading
Loading
Loading
+5 −4
Original line number Diff line number Diff line
@@ -1479,8 +1479,9 @@ static int aio_prep_rw(struct kiocb *req, const struct iocb *iocb)
	return 0;
}

static int aio_setup_rw(int rw, const struct iocb *iocb, struct iovec **iovec,
		bool vectored, bool compat, struct iov_iter *iter)
static ssize_t aio_setup_rw(int rw, const struct iocb *iocb,
		struct iovec **iovec, bool vectored, bool compat,
		struct iov_iter *iter)
{
	void __user *buf = (void __user *)(uintptr_t)iocb->aio_buf;
	size_t len = iocb->aio_nbytes;
@@ -1537,7 +1538,7 @@ static int aio_read(struct kiocb *req, const struct iocb *iocb,
		return -EINVAL;

	ret = aio_setup_rw(READ, iocb, &iovec, vectored, compat, &iter);
	if (ret)
	if (ret < 0)
		return ret;
	ret = rw_verify_area(READ, file, &req->ki_pos, iov_iter_count(&iter));
	if (!ret)
@@ -1565,7 +1566,7 @@ static int aio_write(struct kiocb *req, const struct iocb *iocb,
		return -EINVAL;

	ret = aio_setup_rw(WRITE, iocb, &iovec, vectored, compat, &iter);
	if (ret)
	if (ret < 0)
		return ret;
	ret = rw_verify_area(WRITE, file, &req->ki_pos, iov_iter_count(&iter));
	if (!ret) {
+8 −8
Original line number Diff line number Diff line
@@ -1003,7 +1003,7 @@ static int io_import_fixed(struct io_ring_ctx *ctx, int rw,
	return 0;
}

static int io_import_iovec(struct io_ring_ctx *ctx, int rw,
static ssize_t io_import_iovec(struct io_ring_ctx *ctx, int rw,
			       const struct sqe_submit *s, struct iovec **iovec,
			       struct iov_iter *iter)
{
@@ -1023,7 +1023,7 @@ static int io_import_iovec(struct io_ring_ctx *ctx, int rw,
	opcode = READ_ONCE(sqe->opcode);
	if (opcode == IORING_OP_READ_FIXED ||
	    opcode == IORING_OP_WRITE_FIXED) {
		int ret = io_import_fixed(ctx, rw, sqe, iter);
		ssize_t ret = io_import_fixed(ctx, rw, sqe, iter);
		*iovec = NULL;
		return ret;
	}
@@ -1089,7 +1089,7 @@ static int io_read(struct io_kiocb *req, const struct sqe_submit *s,
	struct iov_iter iter;
	struct file *file;
	size_t iov_count;
	int ret;
	ssize_t ret;

	ret = io_prep_rw(req, s, force_nonblock);
	if (ret)
@@ -1102,7 +1102,7 @@ static int io_read(struct io_kiocb *req, const struct sqe_submit *s,
		return -EINVAL;

	ret = io_import_iovec(req->ctx, READ, s, &iovec, &iter);
	if (ret)
	if (ret < 0)
		return ret;

	iov_count = iov_iter_count(&iter);
@@ -1136,7 +1136,7 @@ static int io_write(struct io_kiocb *req, const struct sqe_submit *s,
	struct iov_iter iter;
	struct file *file;
	size_t iov_count;
	int ret;
	ssize_t ret;

	ret = io_prep_rw(req, s, force_nonblock);
	if (ret)
@@ -1149,7 +1149,7 @@ static int io_write(struct io_kiocb *req, const struct sqe_submit *s,
		return -EINVAL;

	ret = io_import_iovec(req->ctx, WRITE, s, &iovec, &iter);
	if (ret)
	if (ret < 0)
		return ret;

	iov_count = iov_iter_count(&iter);
+4 −4
Original line number Diff line number Diff line
@@ -1356,7 +1356,7 @@ SYSCALL_DEFINE4(vmsplice, int, fd, const struct iovec __user *, uiov,
	struct iovec iovstack[UIO_FASTIOV];
	struct iovec *iov = iovstack;
	struct iov_iter iter;
	long error;
	ssize_t error;
	struct fd f;
	int type;

@@ -1367,7 +1367,7 @@ SYSCALL_DEFINE4(vmsplice, int, fd, const struct iovec __user *, uiov,

	error = import_iovec(type, uiov, nr_segs,
			     ARRAY_SIZE(iovstack), &iov, &iter);
	if (!error) {
	if (error >= 0) {
		error = do_vmsplice(f.file, &iter, flags);
		kfree(iov);
	}
@@ -1382,7 +1382,7 @@ COMPAT_SYSCALL_DEFINE4(vmsplice, int, fd, const struct compat_iovec __user *, io
	struct iovec iovstack[UIO_FASTIOV];
	struct iovec *iov = iovstack;
	struct iov_iter iter;
	long error;
	ssize_t error;
	struct fd f;
	int type;

@@ -1393,7 +1393,7 @@ COMPAT_SYSCALL_DEFINE4(vmsplice, int, fd, const struct compat_iovec __user *, io

	error = compat_import_iovec(type, iov32, nr_segs,
			     ARRAY_SIZE(iovstack), &iov, &iter);
	if (!error) {
	if (error >= 0) {
		error = do_vmsplice(f.file, &iter, flags);
		kfree(iov);
	}
+2 −2
Original line number Diff line number Diff line
@@ -279,13 +279,13 @@ bool csum_and_copy_from_iter_full(void *addr, size_t bytes, __wsum *csum, struct
size_t hash_and_copy_to_iter(const void *addr, size_t bytes, void *hashp,
		struct iov_iter *i);

int import_iovec(int type, const struct iovec __user * uvector,
ssize_t import_iovec(int type, const struct iovec __user * uvector,
		 unsigned nr_segs, unsigned fast_segs,
		 struct iovec **iov, struct iov_iter *i);

#ifdef CONFIG_COMPAT
struct compat_iovec;
int compat_import_iovec(int type, const struct compat_iovec __user * uvector,
ssize_t compat_import_iovec(int type, const struct compat_iovec __user * uvector,
		 unsigned nr_segs, unsigned fast_segs,
		 struct iovec **iov, struct iov_iter *i);
#endif
+8 −7
Original line number Diff line number Diff line
@@ -1634,9 +1634,9 @@ EXPORT_SYMBOL(dup_iter);
 * on-stack array was used or not (and regardless of whether this function
 * returns an error or not).
 *
 * Return: 0 on success or negative error code on error.
 * Return: Negative error code on error, bytes imported on success
 */
int import_iovec(int type, const struct iovec __user * uvector,
ssize_t import_iovec(int type, const struct iovec __user * uvector,
		 unsigned nr_segs, unsigned fast_segs,
		 struct iovec **iov, struct iov_iter *i)
{
@@ -1652,14 +1652,15 @@ int import_iovec(int type, const struct iovec __user * uvector,
	}
	iov_iter_init(i, type, p, nr_segs, n);
	*iov = p == *iov ? NULL : p;
	return 0;
	return n;
}
EXPORT_SYMBOL(import_iovec);

#ifdef CONFIG_COMPAT
#include <linux/compat.h>

int compat_import_iovec(int type, const struct compat_iovec __user * uvector,
ssize_t compat_import_iovec(int type,
		const struct compat_iovec __user * uvector,
		unsigned nr_segs, unsigned fast_segs,
		struct iovec **iov, struct iov_iter *i)
{
@@ -1675,7 +1676,7 @@ int compat_import_iovec(int type, const struct compat_iovec __user * uvector,
	}
	iov_iter_init(i, type, p, nr_segs, n);
	*iov = p == *iov ? NULL : p;
	return 0;
	return n;
}
#endif

Loading