summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJens Axboe <axboe@kernel.dk>2021-12-04 15:55:31 -0700
committerJens Axboe <axboe@kernel.dk>2021-12-04 15:57:30 -0700
commitd84c29b19ed0b130000619cff40141bb1fc3615b (patch)
treebf06ba54eda6552068899225d790d18678a39289
parenta49427fbbe0a2b25cefd77d9a78df2b7d96d661f (diff)
downloadliburing-d84c29b19ed0b130000619cff40141bb1fc3615b.tar.gz
liburing-d84c29b19ed0b130000619cff40141bb1fc3615b.tar.bz2
Don't truncate addr fields to 32-bit on 32-bit
For the commands where we use it as a lookup key, then we don't want to rob 32-bit applications from the potential of using the full 64-bit type. This includes commands like: poll_remove, poll_update, prep_cancel Also provide 64-bit u64 types of the sqe set data and the cqe get data helpers, along with a define that allows applications to check for the presence of it. NOTE: this may trigger compile warnings in applications that currently use these helpers, which is also why a few test cases had to get adapted. The fixup is trivial, and the above define can help applications check if one or the other is the current one. Link: https://github.com/axboe/liburing/issues/490 Reported-by: RĂ©mi Bernon <rbernon@codeweavers.com> Signed-off-by: Jens Axboe <axboe@kernel.dk>
-rw-r--r--src/include/liburing.h47
-rw-r--r--test/accept.c2
-rw-r--r--test/io-cancel.c6
-rw-r--r--test/multicqes_drain.c2
-rw-r--r--test/poll-cancel-ton.c2
-rw-r--r--test/poll-cancel.c2
-rw-r--r--test/poll-mshot-update.c6
7 files changed, 48 insertions, 19 deletions
diff --git a/src/include/liburing.h b/src/include/liburing.h
index 230cd61..3705c5b 100644
--- a/src/include/liburing.h
+++ b/src/include/liburing.h
@@ -219,6 +219,11 @@ static inline void io_uring_cqe_seen(struct io_uring *ring,
/*
* Command prep helpers
*/
+
+/*
+ * Associate pointer @data with the sqe, for later retrieval from the cqe
+ * at command completion time with io_uring_cqe_get_data().
+ */
static inline void io_uring_sqe_set_data(struct io_uring_sqe *sqe, void *data)
{
sqe->user_data = (unsigned long) data;
@@ -229,6 +234,27 @@ static inline void *io_uring_cqe_get_data(const struct io_uring_cqe *cqe)
return (void *) (uintptr_t) cqe->user_data;
}
+/*
+ * Assign a 64-bit value to this sqe, which can get retrieved at completion
+ * time with io_uring_cqe_get_data64. Just like the non-64 variants, except
+ * these store a 64-bit type rather than a data pointer.
+ */
+static inline void io_uring_sqe_set_data64(struct io_uring_sqe *sqe,
+ __u64 data)
+{
+ sqe->user_data = data;
+}
+
+static inline __u64 io_uring_cqe_get_data64(const struct io_uring_cqe *cqe)
+{
+ return cqe->user_data;
+}
+
+/*
+ * Tell the app the have the 64-bit variants of the get/set userdata
+ */
+#define LIBURING_HAVE_DATA64
+
static inline void io_uring_sqe_set_flags(struct io_uring_sqe *sqe,
unsigned flags)
{
@@ -387,18 +413,20 @@ static inline void io_uring_prep_poll_multishot(struct io_uring_sqe *sqe,
}
static inline void io_uring_prep_poll_remove(struct io_uring_sqe *sqe,
- void *user_data)
+ __u64 user_data)
{
- io_uring_prep_rw(IORING_OP_POLL_REMOVE, sqe, -1, user_data, 0, 0);
+ io_uring_prep_rw(IORING_OP_POLL_REMOVE, sqe, -1, NULL, 0, 0);
+ sqe->addr = user_data;
}
static inline void io_uring_prep_poll_update(struct io_uring_sqe *sqe,
- void *old_user_data,
- void *new_user_data,
+ __u64 old_user_data,
+ __u64 new_user_data,
unsigned poll_mask, unsigned flags)
{
- io_uring_prep_rw(IORING_OP_POLL_REMOVE, sqe, -1, old_user_data, flags,
- (__u64)(uintptr_t)new_user_data);
+ io_uring_prep_rw(IORING_OP_POLL_REMOVE, sqe, -1, NULL, flags,
+ new_user_data);
+ sqe->addr = old_user_data;
sqe->poll32_events = __io_uring_prep_poll_mask(poll_mask);
}
@@ -459,10 +487,11 @@ static inline void io_uring_prep_accept_direct(struct io_uring_sqe *sqe, int fd,
__io_uring_set_target_fixed_file(sqe, file_index);
}
-static inline void io_uring_prep_cancel(struct io_uring_sqe *sqe, void *user_data,
- int flags)
+static inline void io_uring_prep_cancel(struct io_uring_sqe *sqe,
+ __u64 user_data, int flags)
{
- io_uring_prep_rw(IORING_OP_ASYNC_CANCEL, sqe, -1, user_data, 0, 0);
+ io_uring_prep_rw(IORING_OP_ASYNC_CANCEL, sqe, -1, NULL, 0, 0);
+ sqe->addr = user_data;
sqe->cancel_flags = (__u32) flags;
}
diff --git a/test/accept.c b/test/accept.c
index a4fc677..af2997f 100644
--- a/test/accept.c
+++ b/test/accept.c
@@ -329,7 +329,7 @@ static int test_accept_cancel(unsigned usecs)
usleep(usecs);
sqe = io_uring_get_sqe(&m_io_uring);
- io_uring_prep_cancel(sqe, (void *) 1, 0);
+ io_uring_prep_cancel(sqe, 1, 0);
sqe->user_data = 2;
ret = io_uring_submit(&m_io_uring);
assert(ret == 1);
diff --git a/test/io-cancel.c b/test/io-cancel.c
index 703ffa7..c1df0df 100644
--- a/test/io-cancel.c
+++ b/test/io-cancel.c
@@ -128,7 +128,7 @@ static int start_cancel(struct io_uring *ring, int do_partial, int async_cancel)
fprintf(stderr, "sqe get failed\n");
goto err;
}
- io_uring_prep_cancel(sqe, (void *) (unsigned long) i + 1, 0);
+ io_uring_prep_cancel(sqe, i + 1, 0);
if (async_cancel)
sqe->flags |= IOSQE_ASYNC;
sqe->user_data = 0;
@@ -246,7 +246,7 @@ static int test_dont_cancel_another_ring(void)
fprintf(stderr, "%s: failed to get sqe\n", __FUNCTION__);
return 1;
}
- io_uring_prep_cancel(sqe, (void *) (unsigned long)1, 0);
+ io_uring_prep_cancel(sqe, 1, 0);
sqe->user_data = 2;
ret = io_uring_submit(&ring2);
@@ -326,7 +326,7 @@ static int test_cancel_req_across_fork(void)
fprintf(stderr, "%s: failed to get sqe\n", __FUNCTION__);
return 1;
}
- io_uring_prep_cancel(sqe, (void *) (unsigned long)1, 0);
+ io_uring_prep_cancel(sqe, 1, 0);
sqe->user_data = 2;
ret = io_uring_submit(&ring);
diff --git a/test/multicqes_drain.c b/test/multicqes_drain.c
index b107a48..148cdd7 100644
--- a/test/multicqes_drain.c
+++ b/test/multicqes_drain.c
@@ -91,7 +91,7 @@ void io_uring_sqe_prep(int op, struct io_uring_sqe *sqe, unsigned sqe_flags, int
io_uring_prep_nop(sqe);
break;
case cancel:
- io_uring_prep_poll_remove(sqe, (void *)(long)arg);
+ io_uring_prep_poll_remove(sqe, arg);
break;
}
sqe->flags = sqe_flags;
diff --git a/test/poll-cancel-ton.c b/test/poll-cancel-ton.c
index f0875cd..05bf565 100644
--- a/test/poll-cancel-ton.c
+++ b/test/poll-cancel-ton.c
@@ -55,7 +55,7 @@ static int del_polls(struct io_uring *ring, int fd, int nr)
sqe = io_uring_get_sqe(ring);
data = sqe_index[lrand48() % nr];
- io_uring_prep_poll_remove(sqe, data);
+ io_uring_prep_poll_remove(sqe, (__u64)(uintptr_t)data);
}
ret = io_uring_submit(ring);
diff --git a/test/poll-cancel.c b/test/poll-cancel.c
index 408159d..6bddc6c 100644
--- a/test/poll-cancel.c
+++ b/test/poll-cancel.c
@@ -79,7 +79,7 @@ static int test_poll_cancel(void)
pds[1].is_poll = 0;
pds[1].is_cancel = 1;
- io_uring_prep_poll_remove(sqe, &pds[0]);
+ io_uring_prep_poll_remove(sqe, (__u64)(uintptr_t)&pds[0]);
io_uring_sqe_set_data(sqe, &pds[1]);
ret = io_uring_submit(&ring);
diff --git a/test/poll-mshot-update.c b/test/poll-mshot-update.c
index 75ee52f..d06699a 100644
--- a/test/poll-mshot-update.c
+++ b/test/poll-mshot-update.c
@@ -42,7 +42,7 @@ static int has_poll_update(void)
return -1;
sqe = io_uring_get_sqe(&ring);
- io_uring_prep_poll_update(sqe, NULL, NULL, POLLIN, IORING_TIMEOUT_UPDATE);
+ io_uring_prep_poll_update(sqe, 0, 0, POLLIN, IORING_TIMEOUT_UPDATE);
ret = io_uring_submit(&ring);
if (ret != 1)
@@ -86,8 +86,8 @@ static int reap_polls(struct io_uring *ring)
sqe = io_uring_get_sqe(ring);
/* update event */
- io_uring_prep_poll_update(sqe, (void *)(unsigned long)i, NULL,
- POLLIN, IORING_POLL_UPDATE_EVENTS);
+ io_uring_prep_poll_update(sqe, i, 0, POLLIN,
+ IORING_POLL_UPDATE_EVENTS);
sqe->user_data = 0x12345678;
}