struct uring_cache *cache;
cache = io_uring_async_get(req);
- if (cache) {
- memcpy(cache->sqes, sqe, uring_sqe_size(req->ctx));
- ioucmd->sqe = req->async_data;
+ if (unlikely(!cache))
+ return -ENOMEM;
+
+ if (!(req->flags & REQ_F_FORCE_ASYNC)) {
+ /* defer memcpy until we need it */
+ ioucmd->sqe = sqe;
return 0;
}
- return -ENOMEM;
+
+ memcpy(req->async_data, sqe, uring_sqe_size(req->ctx));
+ ioucmd->sqe = req->async_data;
+ return 0;
}
int io_uring_cmd_prep(struct io_kiocb *req, const struct io_uring_sqe *sqe)
}
ret = file->f_op->uring_cmd(ioucmd, issue_flags);
- if (ret == -EAGAIN || ret == -EIOCBQUEUED)
- return ret;
+ if (ret == -EAGAIN) {
+ struct uring_cache *cache = req->async_data;
+
+ if (ioucmd->sqe != (void *) cache)
+ memcpy(cache, ioucmd->sqe, uring_sqe_size(req->ctx));
+ return -EAGAIN;
+ } else if (ret == -EIOCBQUEUED) {
+ return -EIOCBQUEUED;
+ }
if (ret < 0)
req_set_fail(req);