| 467 | } |
| 468 | |
| 469 | int queue_remove_entries(cls_method_context_t hctx, const cls_queue_remove_op& op, cls_queue_head& head) |
| 470 | { |
| 471 | //Queue is empty |
| 472 | if ((head.front.offset == head.tail.offset) && (head.front.gen == head.tail.gen)) { |
| 473 | return 0; |
| 474 | } |
| 475 | |
| 476 | cls_queue_marker end_marker; |
| 477 | end_marker.from_str(op.end_marker.c_str()); |
| 478 | |
| 479 | CLS_LOG(5, "INFO: queue_remove_entries: op.end_marker = %s", end_marker.to_str().c_str()); |
| 480 | |
| 481 | //Zero out the entries that have been removed, to reclaim storage space |
| 482 | if (end_marker.offset > head.front.offset && end_marker.gen == head.front.gen) { |
| 483 | uint64_t len = end_marker.offset - head.front.offset; |
| 484 | if (len > 0) { |
| 485 | auto ret = cls_cxx_write_zero(hctx, head.front.offset, len); |
| 486 | if (ret < 0) { |
| 487 | CLS_LOG(5, "INFO: queue_remove_entries: Failed to zero out entries"); |
| 488 | CLS_LOG(10, "INFO: queue_remove_entries: Start offset = %s", head.front.to_str().c_str()); |
| 489 | return ret; |
| 490 | } |
| 491 | } |
| 492 | } else if ((head.front.offset >= end_marker.offset) && (end_marker.gen == head.front.gen + 1)) { //start offset > end offset |
| 493 | uint64_t len = head.queue_size - head.front.offset; |
| 494 | if (len > 0) { |
| 495 | auto ret = cls_cxx_write_zero(hctx, head.front.offset, len); |
| 496 | if (ret < 0) { |
| 497 | CLS_LOG(5, "INFO: queue_remove_entries: Failed to zero out entries"); |
| 498 | CLS_LOG(10, "INFO: queue_remove_entries: Start offset = %s", head.front.to_str().c_str()); |
| 499 | return ret; |
| 500 | } |
| 501 | } |
| 502 | len = end_marker.offset - head.max_head_size; |
| 503 | if (len > 0) { |
| 504 | auto ret = cls_cxx_write_zero(hctx, head.max_head_size, len); |
| 505 | if (ret < 0) { |
| 506 | CLS_LOG(5, "INFO: queue_remove_entries: Failed to zero out entries"); |
| 507 | CLS_LOG(10, "INFO: queue_remove_entries: Start offset = %lu", head.max_head_size); |
| 508 | return ret; |
| 509 | } |
| 510 | } |
| 511 | } else if ((head.front.offset == end_marker.offset) && (head.front.gen == end_marker.gen)) { |
| 512 | //no-op |
| 513 | } else { |
| 514 | CLS_LOG(0, "INFO: queue_remove_entries: Invalid end marker: offset = %s, gen = %lu", end_marker.to_str().c_str(), end_marker.gen); |
| 515 | return -EINVAL; |
| 516 | } |
| 517 | |
| 518 | head.front = end_marker; |
| 519 | |
| 520 | // Check if it is the end, then wrap around |
| 521 | if (head.front.offset == head.queue_size) { |
| 522 | head.front.offset = head.max_head_size; |
| 523 | head.front.gen += 1; |
| 524 | } |
| 525 | |
| 526 | CLS_LOG(20, "INFO: queue_remove_entries: front offset is: %s and tail offset is %s", head.front.to_str().c_str(), head.tail.to_str().c_str()); |
no test coverage detected