rbd: thick-provision images on request

Write blocks of stripe-size to allocate RBD images when
Thick-Provisioning is enabled in the StorageClass.

Signed-off-by: Niels de Vos <ndevos@redhat.com>
This commit is contained in:
Niels de Vos 2020-12-21 17:05:38 +01:00 committed by mergify[bot]
parent c417a5d0ba
commit 5522a05f59

View File

@ -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) 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 return nil
} }
@ -284,6 +294,39 @@ func (rv *rbdVolume) open() (*librbd.Image, error) {
return image, nil 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<<st.Order))
// the actual size of the image as available in the pool, can be
// marginally different from the requested image size
s, err := image.WriteSame(0, st.Size, zeroBlock, rados.OpFlagNone)
util.DebugLog(ctx, "wrote %d bytes to %q", s, rv.String())
return err
}
// isInUse checks if there is a watcher on the image. It returns true if there // isInUse checks if there is a watcher on the image. It returns true if there
// is a watcher on the image, otherwise returns false. // is a watcher on the image, otherwise returns false.
func (rv *rbdVolume) isInUse() (bool, error) { func (rv *rbdVolume) isInUse() (bool, error) {