return waited;
}
-int bdrv_check_request(int64_t offset, int64_t bytes, Error **errp)
+static int bdrv_check_qiov_request(int64_t offset, int64_t bytes,
+ QEMUIOVector *qiov, size_t qiov_offset,
+ Error **errp)
{
+ /*
+ * Check generic offset/bytes correctness
+ */
+
if (offset < 0) {
error_setg(errp, "offset is negative: %" PRIi64, offset);
return -EIO;
return -EIO;
}
+ if (!qiov) {
+ return 0;
+ }
+
+ /*
+ * Check qiov and qiov_offset
+ */
+
+ if (qiov_offset > qiov->size) {
+ error_setg(errp, "qiov_offset(%zu) overflow io vector size(%zu)",
+ qiov_offset, qiov->size);
+ return -EIO;
+ }
+
+ if (bytes > qiov->size - qiov_offset) {
+ error_setg(errp, "bytes(%" PRIi64 ") + qiov_offset(%zu) overflow io "
+ "vector size(%zu)", bytes, qiov_offset, qiov->size);
+ return -EIO;
+ }
+
return 0;
}
-static int bdrv_check_request32(int64_t offset, int64_t bytes)
+int bdrv_check_request(int64_t offset, int64_t bytes, Error **errp)
+{
+ return bdrv_check_qiov_request(offset, bytes, NULL, 0, errp);
+}
+
+static int bdrv_check_request32(int64_t offset, int64_t bytes,
+ QEMUIOVector *qiov, size_t qiov_offset)
{
- int ret = bdrv_check_request(offset, bytes, NULL);
+ int ret = bdrv_check_qiov_request(offset, bytes, qiov, qiov_offset, NULL);
if (ret < 0) {
return ret;
}
return -ENOMEDIUM;
}
- ret = bdrv_check_request32(offset, bytes);
+ ret = bdrv_check_request32(offset, bytes, qiov, qiov_offset);
if (ret < 0) {
return ret;
}
return -ENOMEDIUM;
}
- ret = bdrv_check_request32(offset, bytes);
+ ret = bdrv_check_request32(offset, bytes, qiov, qiov_offset);
if (ret < 0) {
return ret;
}
if (!dst || !dst->bs || !bdrv_is_inserted(dst->bs)) {
return -ENOMEDIUM;
}
- ret = bdrv_check_request32(dst_offset, bytes);
+ ret = bdrv_check_request32(dst_offset, bytes, NULL, 0);
if (ret) {
return ret;
}
if (!src || !src->bs || !bdrv_is_inserted(src->bs)) {
return -ENOMEDIUM;
}
- ret = bdrv_check_request32(src_offset, bytes);
+ ret = bdrv_check_request32(src_offset, bytes, NULL, 0);
if (ret) {
return ret;
}