| 794 | } |
| 795 | |
| 796 | extern "C" int ceph_file_blockdiff(struct ceph_file_blockdiff_info* info, |
| 797 | struct ceph_file_blockdiff_changedblocks* blocks) |
| 798 | { |
| 799 | if (!info->cmount->is_mounted()) { |
| 800 | return -ENOTCONN; |
| 801 | } |
| 802 | |
| 803 | std::vector<std::pair<uint64_t,uint64_t>> _blocks; |
| 804 | struct scan_state_t *state = reinterpret_cast<scan_state_t *>(info->blockp); |
| 805 | |
| 806 | int r = info->cmount->get_client()->file_blockdiff(state, info->cmount->default_perms, &_blocks); |
| 807 | if (r < 0) { |
| 808 | return r; |
| 809 | } |
| 810 | |
| 811 | blocks->b = NULL; |
| 812 | blocks->num_blocks = _blocks.size(); |
| 813 | if (blocks->num_blocks) { |
| 814 | struct cblock *b = (struct cblock *)calloc(blocks->num_blocks, sizeof(struct cblock)); |
| 815 | if (!b) { |
| 816 | return -ENOMEM; |
| 817 | } |
| 818 | |
| 819 | struct cblock *_b = b; |
| 820 | for (auto &_block : _blocks) { |
| 821 | _b->offset = _block.first; |
| 822 | _b->len = _block.second; |
| 823 | ++_b; |
| 824 | } |
| 825 | |
| 826 | blocks->b = b; |
| 827 | } |
| 828 | |
| 829 | return r; |
| 830 | } |
| 831 | |
| 832 | extern "C" void ceph_free_file_blockdiff_buffer(struct ceph_file_blockdiff_changedblocks* blocks) |
| 833 | { |