int krbd_resize(struct rbd_ctx *ctx, uint64_t size) { int ret; assert(size % truncbdy == 0); /* * When krbd detects a size change, it calls revalidate_disk(), * which ends up calling invalidate_bdev(), which invalidates * clean pages and does nothing about dirty pages beyond the * new size. The preceding cache flush makes sure those pages * are invalidated, which is what we need on shrink: * * write 0..1M * resize 0 * resize 2M * write 1..2M * * results in "data data" rather than "0000 data". */ ret = __krbd_flush(ctx); if (ret < 0) return ret; return __librbd_resize(ctx, size); }
int krbd_discard(struct rbd_ctx *ctx, uint64_t off, uint64_t len) { uint64_t range[2] = { off, len }; int ret; /* * BLKDISCARD doesn't affect dirty pages. This means we can't * rely on discarded sectors to match good_buf (i.e. contain * zeros) without a preceding cache flush: * * write 0..3M * discard 1..2M * * results in "data data data" rather than "data 0000 data". */ ret = __krbd_flush(ctx); if (ret < 0) return ret; /* * off and len must be 512-byte aligned, otherwise BLKDISCARD * will fail with -EINVAL. This means that -K (enable krbd * mode) requires -h 512 or similar. */ if (ioctl(ctx->krbd_fd, BLKDISCARD, &range) < 0) { ret = -errno; prt("BLKDISCARD(%llu, %llu) failed\n", off, len); return ret; } return 0; }
int krbd_flatten(struct rbd_ctx *ctx) { int ret; ret = __krbd_flush(ctx); if (ret < 0) return ret; return __librbd_flatten(ctx); }
int krbd_clone(struct rbd_ctx *ctx, const char *src_snapname, const char *dst_imagename, int *order, int stripe_unit, int stripe_count) { int ret; ret = __krbd_flush(ctx); if (ret < 0) return ret; return __librbd_clone(ctx, src_snapname, dst_imagename, order, stripe_unit, stripe_count); }
int krbd_resize(struct rbd_ctx *ctx, uint64_t size) { int ret; assert(size % truncbdy == 0); /* * This is essential: when krbd detects a size change, it calls * revalidate_disk(), which ends up calling invalidate_bdev(), * which invalidates only clean buffers. The cache flush makes * it invalidate everything, which is what we need if we are * shrinking. */ ret = __krbd_flush(ctx); if (ret < 0) return ret; return __librbd_resize(ctx, size); }
int krbd_flush(struct rbd_ctx *ctx) { return __krbd_flush(ctx); }