| 649 | } |
| 650 | |
| 651 | static int cls_2pc_queue_remove_entries(cls_method_context_t hctx, bufferlist *in, bufferlist *out) |
| 652 | { |
| 653 | auto in_iter = in->cbegin(); |
| 654 | cls_2pc_queue_remove_op rem_2pc_op; |
| 655 | try { |
| 656 | decode(rem_2pc_op, in_iter); |
| 657 | } catch (ceph::buffer::error& err) { |
| 658 | CLS_LOG(1, "ERROR: cls_2pc_queue_remove_entries: failed to decode entry: %s", err.what()); |
| 659 | return -EINVAL; |
| 660 | } |
| 661 | |
| 662 | cls_queue_head head; |
| 663 | auto ret = queue_read_head(hctx, head); |
| 664 | if (ret < 0) { |
| 665 | return ret; |
| 666 | } |
| 667 | |
| 668 | // Old RGW is running, and it sent cls_queue_remove_op instead of cls_2pc_queue_remove_op |
| 669 | if (rem_2pc_op.entries_to_remove == 0) { |
| 670 | CLS_LOG(10, "INFO: cls_2pc_queue_remove_entries: incompatible RGW with rados, counting entries to remove..."); |
| 671 | cls_queue_list_op list_op; |
| 672 | list_op.max = std::numeric_limits<uint64_t>::max(); // max length because endmarker is the stopping condition. |
| 673 | list_op.end_marker = rem_2pc_op.end_marker; |
| 674 | ret = cls_2pc_queue_count_entries(hctx, list_op, head, rem_2pc_op.entries_to_remove); |
| 675 | if (ret < 0) { |
| 676 | CLS_LOG(1, "ERROR: cls_2pc_queue_remove_entries: returned: %d", ret); |
| 677 | return ret; |
| 678 | } |
| 679 | CLS_LOG(10, "INFO: cls_2pc_queue_remove_entries: counted: %u", rem_2pc_op.entries_to_remove); |
| 680 | } |
| 681 | |
| 682 | cls_queue_remove_op rem_op; |
| 683 | rem_op.end_marker = std::move(rem_2pc_op.end_marker); |
| 684 | ret = queue_remove_entries(hctx, rem_op, head); |
| 685 | if (ret < 0) { |
| 686 | return ret; |
| 687 | } |
| 688 | |
| 689 | cls_2pc_urgent_data urgent_data; |
| 690 | try { |
| 691 | auto in_iter = head.bl_urgent_data.cbegin(); |
| 692 | decode(urgent_data, in_iter); |
| 693 | } catch (ceph::buffer::error& err) { |
| 694 | CLS_LOG(1, "ERROR: cls_2pc_queue_remove_entries: failed to decode header of queue: %s", err.what()); |
| 695 | return -EINVAL; |
| 696 | } |
| 697 | urgent_data.committed_entries -= rem_2pc_op.entries_to_remove; |
| 698 | // write back head |
| 699 | head.bl_urgent_data.clear(); |
| 700 | encode(urgent_data, head.bl_urgent_data); |
| 701 | |
| 702 | return queue_write_head(hctx, head); |
| 703 | } |
| 704 | |
| 705 | CLS_INIT(2pc_queue) |
| 706 | { |