diff --git a/interfaces/kits/hyperaio/include/hyperaio.h b/interfaces/kits/hyperaio/include/hyperaio.h index f7f64104cec9fa78cd531fc15862354d3572c36a..d13b9ef9b4add5cc2486f76e11ebfbbf9b10967f 100644 --- a/interfaces/kits/hyperaio/include/hyperaio.h +++ b/interfaces/kits/hyperaio/include/hyperaio.h @@ -97,6 +97,9 @@ private: std::atomic stopThread_ = true; std::atomic initialized_ = false; void HarvestRes(); + void HandleRequestError(std::vector &errorVec, int32_t errorcode); + void HandleSqeError(uint32_t count, std::vector &infoVec); + int32_t CheckParameter(uint32_t reqNum); }; } } diff --git a/interfaces/kits/hyperaio/src/hyperaio.cpp b/interfaces/kits/hyperaio/src/hyperaio.cpp index 1f5dc006db5daa9b77efbde83ea1972fc9105c87..c2a2ded0f539c05966614cc62589803e3ebfbc81 100644 --- a/interfaces/kits/hyperaio/src/hyperaio.cpp +++ b/interfaces/kits/hyperaio/src/hyperaio.cpp @@ -114,30 +114,76 @@ int32_t HyperAio::CtxInit(ProcessIoResultCallBack *callBack) return EOK; } -int32_t HyperAio::StartOpenReqs(OpenReqs *req) +void HyperAio::HandleRequestError(std::vector &errorVec, int32_t errorcode) { - if (pImpl_ == nullptr) { - return -EINVAL; + if (errorVec.empty()) { + HILOGE("errorVec is empty"); + return; } - if (req == nullptr || req->reqs == nullptr) { + for (auto &userdata : errorVec) { + HILOGE("HandleRequestError: userData = %{public}lu", userdata); + auto response = std::make_unique(userdata, errorcode, 0); + ioResultCallBack_(std::move(response)); + } + errorVec.clear(); +} + +void HyperAio::HandleSqeError(uint32_t count, std::vector &infoVec) +{ + if (count > 0) { + int32_t ret = io_uring_submit(&pImpl_->uring_); + if (ret < 0) { + HILOGE("submit read reqs failed, ret = %{public}d", ret); + HandleRequestError(infoVec, ret); + } + readReqCount_ += count; + } +} + +int32_t HyperAio::CheckParameter(uint32_t reqNum) +{ + if (pImpl_ == nullptr) { + HILOGE("pImpl is not initialized"); return -EINVAL; } if (!initialized_.load()) { HILOGE("HyperAio is not initialized"); return -EPERM; } - if (!ValidateReqNum(req->reqNum)) { - HILOGE("reqNum is out of range: %{public}u", req->reqNum); + if (!ValidateReqNum(reqNum)) { + HILOGE("reqNum is out of range: %{public}u", reqNum); return -EINVAL; } + return EOK; +} + +int32_t HyperAio::StartOpenReqs(OpenReqs *req) +{ + if (req == nullptr || req->reqs == nullptr) { + HILOGE("the request is empty"); + return -EINVAL; + } + + int32_t ret = CheckParameter(req->reqNum); + if (ret < 0) { + return ret; + } + HyperaioTrace trace("StartOpenReqs" + std::to_string(req->reqNum)); uint32_t totalReqs = req->reqNum; uint32_t count = 0; + std::vector errorVec; + std::vector openInfoVec; for (uint32_t i = 0; i < totalReqs; i++) { struct io_uring_sqe *sqe = GetSqeWithRetry(&pImpl_->uring_); if (sqe == nullptr) { HILOGE("get sqe failed"); - return -ENOMEM; + for (; i < totalReqs; ++i) { + errorVec.push_back(req->reqs[i].userData); + } + HandleSqeError(count, openInfoVec); + HandleRequestError(errorVec, -EBUSY); + break; } struct OpenInfo *openInfo = &req->reqs[i]; io_uring_sqe_set_data(sqe, reinterpret_cast(openInfo->userData)); @@ -148,11 +194,12 @@ int32_t HyperAio::StartOpenReqs(OpenReqs *req) HyperaioTrace trace("open flags:" + std::to_string(openInfo->flags) + "mode:" + std::to_string(openInfo->mode) + "userData:" + std::to_string(openInfo->userData)); count++; + openInfoVec.push_back(openInfo->userData); if (count >= BATCH_SIZE || i == totalReqs - 1) { int32_t ret = io_uring_submit(&pImpl_->uring_); if (ret < 0) { HILOGE("submit open reqs failed, ret = %{public}d", ret); - return ret; + HandleRequestError(openInfoVec, -EBUSY); } openReqCount_ += count; count = 0; @@ -163,28 +210,30 @@ int32_t HyperAio::StartOpenReqs(OpenReqs *req) int32_t HyperAio::StartReadReqs(ReadReqs *req) { - if (pImpl_ == nullptr) { - return -EINVAL; - } if (req == nullptr || req->reqs == nullptr) { + HILOGE("the request is empty"); return -EINVAL; } - if (!initialized_.load()) { - HILOGE("HyperAio is not initialized"); - return -EPERM; - } - if (!ValidateReqNum(req->reqNum)) { - HILOGE("reqNum is out of range: %{public}u", req->reqNum); - return -EINVAL; + + int32_t ret = CheckParameter(req->reqNum); + if (ret < 0) { + return ret; } HyperaioTrace trace("StartReadReqs" + std::to_string(req->reqNum)); uint32_t totalReqs = req->reqNum; uint32_t count = 0; + std::vector errorVec; + std::vector readInfoVec; for (uint32_t i = 0; i < totalReqs; i++) { struct io_uring_sqe *sqe = GetSqeWithRetry(&pImpl_->uring_); if (sqe == nullptr) { HILOGE("get sqe failed"); - return -ENOMEM; + for (; i < totalReqs; ++i) { + errorVec.push_back(req->reqs[i].userData); + } + HandleSqeError(count, readInfoVec); + HandleRequestError(errorVec, -EBUSY); + break; } struct ReadInfo *readInfo = &req->reqs[i]; io_uring_sqe_set_data(sqe, reinterpret_cast(readInfo->userData)); @@ -194,11 +243,12 @@ int32_t HyperAio::StartReadReqs(ReadReqs *req) HyperaioTrace trace("read len:" + std::to_string(readInfo->len) + "offset:" + std::to_string(readInfo->offset) + "userData:" + std::to_string(readInfo->userData)); count++; + readInfoVec.push_back(readInfo->userData); if (count >= BATCH_SIZE || i == totalReqs - 1) { int32_t ret = io_uring_submit(&pImpl_->uring_); if (ret < 0) { HILOGE("submit read reqs failed, ret = %{public}d", ret); - return ret; + HandleRequestError(readInfoVec, -EBUSY); } readReqCount_ += count; count = 0; @@ -209,28 +259,30 @@ int32_t HyperAio::StartReadReqs(ReadReqs *req) int32_t HyperAio::StartCancelReqs(CancelReqs *req) { - if (pImpl_ == nullptr) { - return -EINVAL; - } if (req == nullptr || req->reqs == nullptr) { + HILOGE("the request is empty"); return -EINVAL; } - if (!initialized_.load()) { - HILOGE("HyperAio is not initialized"); - return -EPERM; - } - if (!ValidateReqNum(req->reqNum)) { - HILOGE("reqNum is out of range: %{public}u", req->reqNum); - return -EINVAL; + + int32_t ret = CheckParameter(req->reqNum); + if (ret < 0) { + return ret; } HyperaioTrace trace("StartCancelReqs" + std::to_string(req->reqNum)); uint32_t totalReqs = req->reqNum; uint32_t count = 0; + std::vector errorVec; + std::vector cancelInfoVec; for (uint32_t i = 0; i < totalReqs; i++) { struct io_uring_sqe *sqe = GetSqeWithRetry(&pImpl_->uring_); if (sqe == nullptr) { HILOGE("get sqe failed"); - return -ENOMEM; + for (; i < totalReqs; ++i) { + errorVec.push_back(req->reqs[i].userData); + } + HandleSqeError(count, cancelInfoVec); + HandleRequestError(errorVec, -EBUSY); + break; } struct CancelInfo *cancelInfo = &req->reqs[i]; io_uring_sqe_set_data(sqe, reinterpret_cast(cancelInfo->userData)); @@ -240,11 +292,12 @@ int32_t HyperAio::StartCancelReqs(CancelReqs *req) HyperaioTrace trace("cancel userData:" + std::to_string(cancelInfo->userData) + "targetUserData:" + std::to_string(cancelInfo->targetUserData)); count++; + cancelInfoVec.push_back(cancelInfo->userData); if (count >= BATCH_SIZE || i == totalReqs - 1) { int32_t ret = io_uring_submit(&pImpl_->uring_); if (ret < 0) { HILOGE("submit cancel reqs failed, ret = %{public}d", ret); - return ret; + HandleRequestError(cancelInfoVec, -EBUSY); } cancelReqCount_ += count; count = 0; diff --git a/interfaces/test/unittest/hyperaio/hyperaio_test.cpp b/interfaces/test/unittest/hyperaio/hyperaio_test.cpp index b1916adbd090218beea36cd19246248bff1b1a05..0aa3de24bcffec82d714cebba8bd0ee877b0642a 100644 --- a/interfaces/test/unittest/hyperaio/hyperaio_test.cpp +++ b/interfaces/test/unittest/hyperaio/hyperaio_test.cpp @@ -240,8 +240,12 @@ namespace OHOS::HyperAio { EXPECT_EQ(result, 0); sqe_flag = false; result = hyperAio_->StartOpenReqs(&openReqs); - EXPECT_EQ(result, -ENOMEM); + EXPECT_EQ(result, 0); sqe_flag = true; + submit_flag = false; + result = hyperAio_->StartOpenReqs(&openReqs); + EXPECT_EQ(result, 0); + submit_flag = true; result = hyperAio_->DestroyCtx(); EXPECT_EQ(result, 0); GTEST_LOG_(INFO) << "HyperAioTest-end HyperAio_StartOpenReqs_0003"; @@ -381,8 +385,12 @@ namespace OHOS::HyperAio { EXPECT_EQ(result, 0); sqe_flag = false; result = hyperAio_->StartReadReqs(&readReqs); - EXPECT_EQ(result, -ENOMEM); + EXPECT_EQ(result, 0); sqe_flag = true; + submit_flag = false; + result = hyperAio_->StartReadReqs(&readReqs); + EXPECT_EQ(result, 0); + submit_flag = true; result = hyperAio_->DestroyCtx(); EXPECT_EQ(result, 0); GTEST_LOG_(INFO) << "HyperAioTest-end HyperAio_StartReadReqs_0003"; @@ -518,8 +526,12 @@ namespace OHOS::HyperAio { EXPECT_EQ(result, 0); sqe_flag = false; result = hyperAio_->StartCancelReqs(&cancelReqs); - EXPECT_EQ(result, -ENOMEM); + EXPECT_EQ(result, 0); sqe_flag = true; + submit_flag = false; + result = hyperAio_->StartCancelReqs(&cancelReqs); + EXPECT_EQ(result, 0); + submit_flag = true; result = hyperAio_->DestroyCtx(); EXPECT_EQ(result, 0); GTEST_LOG_(INFO) << "HyperAioTest-end HyperAio_StartCancelReqs_0003"; diff --git a/interfaces/test/unittest/hyperaio/include/liburing.h b/interfaces/test/unittest/hyperaio/include/liburing.h index b00112be3c3b823357047843934b4b6ad5451c7e..e5b53ba3544fdee818751eb2ce6332ad8405c61b 100644 --- a/interfaces/test/unittest/hyperaio/include/liburing.h +++ b/interfaces/test/unittest/hyperaio/include/liburing.h @@ -25,6 +25,7 @@ inline bool sqe_flag = true; inline bool init_flag = true; inline bool wait_flag = true; inline bool cqe_res_flag = true; +inline bool submit_flag = true; struct io_uring_sqe { int32_t data; }; @@ -56,6 +57,7 @@ struct io_uring { inline struct io_uring_sqe *io_uring_get_sqe(struct io_uring *ring) { if (sqe_flag) { + sqe_flag = !sqe_flag; return ring->io_uring_get_sqe(); } return nullptr; @@ -63,11 +65,15 @@ inline struct io_uring_sqe *io_uring_get_sqe(struct io_uring *ring) inline int io_uring_submit(struct io_uring *ring) { - return 1; + if (submit_flag) { + return 1; + } + return -1; } inline int io_uring_queue_init(unsigned entries, struct io_uring *ring, unsigned flags) { + sqe_flag = true; if (init_flag) { return 1; }