| 285 | } |
| 286 | |
| 287 | int SimpleRADOSStriper::shrink_alloc(uint64_t a) |
| 288 | { |
| 289 | d(5) << dendl; |
| 290 | std::vector<aiocompletionptr> removes; |
| 291 | |
| 292 | ceph_assert(a <= allocated); |
| 293 | uint64_t prune = std::max<uint64_t>(a, (1u << object_size)); /* never delete first extent here */ |
| 294 | uint64_t len = allocated - prune; |
| 295 | const uint64_t bytes_removed = len; |
| 296 | uint64_t offset = prune; |
| 297 | while (len > 0) { |
| 298 | auto ext = get_next_extent(offset, len); |
| 299 | auto aiocp = aiocompletionptr(librados::Rados::aio_create_completion()); |
| 300 | if (int rc = ioctx.aio_remove(ext.soid, aiocp.get()); rc < 0) { |
| 301 | d(1) << " aio_remove failed: " << cpp_strerror(rc) << dendl; |
| 302 | return rc; |
| 303 | } |
| 304 | removes.emplace_back(std::move(aiocp)); |
| 305 | len -= ext.len; |
| 306 | offset += ext.len; |
| 307 | } |
| 308 | |
| 309 | for (auto& aiocp : removes) { |
| 310 | if (int rc = aiocp->wait_for_complete(); rc < 0 && rc != -ENOENT) { |
| 311 | d(1) << " aio_remove failed: " << cpp_strerror(rc) << dendl; |
| 312 | return rc; |
| 313 | } |
| 314 | } |
| 315 | |
| 316 | auto ext = get_first_extent(); |
| 317 | auto op = librados::ObjectWriteOperation(); |
| 318 | auto aiocp = aiocompletionptr(librados::Rados::aio_create_completion()); |
| 319 | op.setxattr(XATTR_ALLOCATED, uint2bl(a)); |
| 320 | d(15) << " updating allocated to " << a << dendl; |
| 321 | op.setxattr(XATTR_VERSION, uint2bl(version+1)); |
| 322 | d(15) << " updating version to " << (version+1) << dendl; |
| 323 | if (int rc = ioctx.aio_operate(ext.soid, aiocp.get(), &op); rc < 0) { |
| 324 | d(1) << " update failed: " << cpp_strerror(rc) << dendl; |
| 325 | return rc; |
| 326 | } |
| 327 | /* we need to wait so we don't have dangling extents */ |
| 328 | d(10) << " waiting for allocated update" << dendl; |
| 329 | if (int rc = aiocp->wait_for_complete(); rc < 0) { |
| 330 | d(1) << " update failure: " << cpp_strerror(rc) << dendl; |
| 331 | return rc; |
| 332 | } |
| 333 | if (logger) { |
| 334 | logger->inc(P_UPDATE_METADATA); |
| 335 | logger->inc(P_UPDATE_ALLOCATED); |
| 336 | logger->inc(P_UPDATE_VERSION); |
| 337 | logger->inc(P_SHRINK); |
| 338 | logger->inc(P_SHRINK_BYTES, bytes_removed); |
| 339 | } |
| 340 | |
| 341 | version += 1; |
| 342 | allocated = a; |
| 343 | return 0; |
| 344 | } |
nothing calls this directly
no test coverage detected