diff --git a/internal/rbd/rbd_util.go b/internal/rbd/rbd_util.go index ddc2fb17d..4d60c5ad2 100644 --- a/internal/rbd/rbd_util.go +++ b/internal/rbd/rbd_util.go @@ -224,6 +224,16 @@ func createImage(ctx context.Context, pOpts *rbdVolume, cr *util.Credentials) er return fmt.Errorf("failed to create rbd image: %w", err) } + if pOpts.ThickProvision { + err = pOpts.allocate(ctx) + if err != nil { + // nolint:errcheck // deleteImage() will log errors in + // case it fails, no need to log them here again + _ = deleteImage(ctx, pOpts, cr) + return fmt.Errorf("failed to thick provision image: %w", err) + } + } + return nil } @@ -284,6 +294,39 @@ func (rv *rbdVolume) open() (*librbd.Image, error) { return image, nil } +// allocate uses the stripe-period of the image to fully allocate (thick +// provision) the image. +func (rv *rbdVolume) allocate(ctx context.Context) error { + util.DebugLog(ctx, "going to allocate %q with %d bytes, this may take time", rv.String(), rv.VolSize) + + image, err := rv.open() + if err != nil { + return err + } + defer image.Close() + + st, err := image.Stat() + if err != nil { + return err + } + + sc, err := image.GetStripeCount() + if err != nil { + return err + } + + // zeroBlock is the stripe-period: size of the object-size multiplied + // by the stripe-count + zeroBlock := make([]byte, sc*(1<