diff --git a/internal/rbd/controllerserver.go b/internal/rbd/controllerserver.go index 20f3a868b..d12e35739 100644 --- a/internal/rbd/controllerserver.go +++ b/internal/rbd/controllerserver.go @@ -175,6 +175,33 @@ func getGRPCErrorForCreateVolume(err error) error { return status.Error(codes.Internal, err.Error()) } +// validateRequestedVolumeSize validates the request volume size with the +// source snapshot or volume size, if there is a size missmatch it returns an error. +func validateRequestedVolumeSize(rbdVol, parentVol *rbdVolume, rbdSnap *rbdSnapshot, cr *util.Credentials) error { + if rbdSnap != nil { + vol := generateVolFromSnap(rbdSnap) + err := vol.Connect(cr) + if err != nil { + return status.Error(codes.Internal, err.Error()) + } + defer vol.Destroy() + + err = vol.getImageInfo() + if err != nil { + return status.Error(codes.Internal, err.Error()) + } + if rbdVol.VolSize != vol.VolSize { + return status.Errorf(codes.InvalidArgument, "size missmatch, requested volume size %d and source snapshot size %d", rbdVol.VolSize, vol.VolSize) + } + } + if parentVol != nil { + if rbdVol.VolSize != parentVol.VolSize { + return status.Errorf(codes.InvalidArgument, "size missmatch, requested volume size %d and source volume size %d", rbdVol.VolSize, parentVol.VolSize) + } + } + return nil +} + // CreateVolume creates the volume in backend func (cs *ControllerServer) CreateVolume(ctx context.Context, req *csi.CreateVolumeRequest) (*csi.CreateVolumeResponse, error) { if err := cs.validateVolumeReq(ctx, req); err != nil { @@ -227,6 +254,11 @@ func (cs *ControllerServer) CreateVolume(ctx context.Context, req *csi.CreateVol return buildCreateVolumeResponse(ctx, req, rbdVol) } + err = validateRequestedVolumeSize(rbdVol, parentVol, rbdSnap, cr) + if err != nil { + return nil, err + } + err = flattenParentImage(ctx, parentVol, cr) if err != nil { return nil, err