diff --git a/deploy/helm/charts/charts/crds/templates/zfsrestore.yaml b/deploy/helm/charts/charts/crds/templates/zfsrestore.yaml index f43f1f69b..ec35b1e38 100644 --- a/deploy/helm/charts/charts/crds/templates/zfsrestore.yaml +++ b/deploy/helm/charts/charts/crds/templates/zfsrestore.yaml @@ -163,6 +163,14 @@ spec: been provisioned. minLength: 1 type: string + quotaType: + description: 'quotaType determines whether the dataset volume quota + type is of type "quota" or "refquota". QuotaType can not be modified + once volume has been provisioned. Default Value: quota.' + enum: + - quota + - refquota + type: string recordsize: description: 'Specifies a suggested block size for files in the file system. The size specified must be a power of two greater than or diff --git a/deploy/helm/charts/charts/crds/templates/zfssnapshot.yaml b/deploy/helm/charts/charts/crds/templates/zfssnapshot.yaml index 38cf98f84..93f091c89 100644 --- a/deploy/helm/charts/charts/crds/templates/zfssnapshot.yaml +++ b/deploy/helm/charts/charts/crds/templates/zfssnapshot.yaml @@ -132,6 +132,14 @@ spec: been provisioned. minLength: 1 type: string + quotaType: + description: 'quotaType determines whether the dataset volume quota + type is of type "quota" or "refquota". QuotaType can not be modified + once volume has been provisioned. Default Value: quota.' + enum: + - quota + - refquota + type: string recordsize: description: 'Specifies a suggested block size for files in the file system. The size specified must be a power of two greater than or diff --git a/deploy/helm/charts/charts/crds/templates/zfsvolume.yaml b/deploy/helm/charts/charts/crds/templates/zfsvolume.yaml index cfb1aad86..c9a46a604 100644 --- a/deploy/helm/charts/charts/crds/templates/zfsvolume.yaml +++ b/deploy/helm/charts/charts/crds/templates/zfsvolume.yaml @@ -158,6 +158,14 @@ spec: been provisioned. minLength: 1 type: string + quotaType: + description: 'quotaType determines whether the dataset volume quota + type is of type "quota" or "refquota". QuotaType can not be modified + once volume has been provisioned. Default Value: quota.' + enum: + - quota + - refquota + type: string recordsize: description: 'Specifies a suggested block size for files in the file system. The size specified must be a power of two greater than or diff --git a/deploy/yamls/zfsrestore-crd.yaml b/deploy/yamls/zfsrestore-crd.yaml index ffffb711b..b17c9c120 100644 --- a/deploy/yamls/zfsrestore-crd.yaml +++ b/deploy/yamls/zfsrestore-crd.yaml @@ -163,6 +163,14 @@ spec: been provisioned. minLength: 1 type: string + quotaType: + description: 'quotaType determines whether the dataset volume quota + type is of type "quota" or "refquota". QuotaType can not be modified + once volume has been provisioned. Default Value: quota.' + enum: + - quota + - refquota + type: string recordsize: description: 'Specifies a suggested block size for files in the file system. The size specified must be a power of two greater than or diff --git a/deploy/yamls/zfssnapshot-crd.yaml b/deploy/yamls/zfssnapshot-crd.yaml index fb6a9af9e..b98066a73 100644 --- a/deploy/yamls/zfssnapshot-crd.yaml +++ b/deploy/yamls/zfssnapshot-crd.yaml @@ -132,6 +132,14 @@ spec: been provisioned. minLength: 1 type: string + quotaType: + description: 'quotaType determines whether the dataset volume quota + type is of type "quota" or "refquota". QuotaType can not be modified + once volume has been provisioned. Default Value: quota.' + enum: + - quota + - refquota + type: string recordsize: description: 'Specifies a suggested block size for files in the file system. The size specified must be a power of two greater than or diff --git a/deploy/yamls/zfsvolume-crd.yaml b/deploy/yamls/zfsvolume-crd.yaml index aeb00f5ac..9c0836050 100644 --- a/deploy/yamls/zfsvolume-crd.yaml +++ b/deploy/yamls/zfsvolume-crd.yaml @@ -158,6 +158,14 @@ spec: been provisioned. minLength: 1 type: string + quotaType: + description: 'quotaType determines whether the dataset volume quota + type is of type "quota" or "refquota". QuotaType can not be modified + once volume has been provisioned. Default Value: quota.' + enum: + - quota + - refquota + type: string recordsize: description: 'Specifies a suggested block size for files in the file system. The size specified must be a power of two greater than or diff --git a/deploy/zfs-operator.yaml b/deploy/zfs-operator.yaml index 8c42495cc..321337d90 100644 --- a/deploy/zfs-operator.yaml +++ b/deploy/zfs-operator.yaml @@ -179,6 +179,14 @@ spec: been provisioned. minLength: 1 type: string + quotaType: + description: 'quotaType determines whether the dataset volume quota + type is of type "quota" or "refquota". QuotaType can not be modified + once volume has been provisioned. Default Value: quota.' + enum: + - quota + - refquota + type: string recordsize: description: 'Specifies a suggested block size for files in the file system. The size specified must be a power of two greater than or @@ -602,6 +610,14 @@ spec: been provisioned. minLength: 1 type: string + quotaType: + description: 'quotaType determines whether the dataset volume quota + type is of type "quota" or "refquota". QuotaType can not be modified + once volume has been provisioned. Default Value: quota.' + enum: + - quota + - refquota + type: string recordsize: description: 'Specifies a suggested block size for files in the file system. The size specified must be a power of two greater than or @@ -1132,6 +1148,14 @@ spec: been provisioned. minLength: 1 type: string + quotaType: + description: 'quotaType determines whether the dataset volume quota + type is of type "quota" or "refquota". QuotaType can not be modified + once volume has been provisioned. Default Value: quota.' + enum: + - quota + - refquota + type: string recordsize: description: 'Specifies a suggested block size for files in the file system. The size specified must be a power of two greater than or diff --git a/pkg/apis/openebs.io/zfs/v1/zfsvolume.go b/pkg/apis/openebs.io/zfs/v1/zfsvolume.go index 5ee93f7bb..cb529a0a0 100644 --- a/pkg/apis/openebs.io/zfs/v1/zfsvolume.go +++ b/pkg/apis/openebs.io/zfs/v1/zfsvolume.go @@ -163,6 +163,12 @@ type VolumeInfo struct { // +kubebuilder:validation:Enum=ZVOL;DATASET VolumeType string `json:"volumeType"` + // quotaType determines whether the dataset volume quota type is of type "quota" or "refquota". + // QuotaType can not be modified once volume has been provisioned. + // +kubebuilder:validation:Enum=quota;refquota + // Default Value: quota. + QuotaType string `json:"quotaType,omitempty"` + // FsType specifies filesystem type for the zfs volume/dataset. // If FsType is provided as "zfs", then the driver will create a // ZFS dataset, formatting is not required as underlying filesystem is ZFS anyway. diff --git a/pkg/builder/volbuilder/build.go b/pkg/builder/volbuilder/build.go index 140575a6c..d1913e4f3 100644 --- a/pkg/builder/volbuilder/build.go +++ b/pkg/builder/volbuilder/build.go @@ -172,6 +172,16 @@ func (b *Builder) WithFsType(fstype string) *Builder { return b } +// WithQuotaType sets quota type for dataset volume +func (b *Builder) WithQuotaType(quotatype string) *Builder { + if quotatype != "" { + b.volume.Object.Spec.QuotaType = quotatype + } else { + b.volume.Object.Spec.QuotaType = "quota" + } + return b +} + // WithShared sets where filesystem is shared or not func (b *Builder) WithShared(shared string) *Builder { b.volume.Object.Spec.Shared = shared diff --git a/pkg/driver/controller.go b/pkg/driver/controller.go index 22bda058f..7f3cfd1ff 100644 --- a/pkg/driver/controller.go +++ b/pkg/driver/controller.go @@ -221,6 +221,7 @@ func CreateZFSVolume(ctx context.Context, req *csi.CreateVolumeRequest) (string, schld := parameters["scheduler"] fstype := parameters["fstype"] shared := parameters["shared"] + quotatype := parameters["quotatype"] vtype := zfs.GetVolumeType(fstype) @@ -279,6 +280,7 @@ func CreateZFSVolume(ctx context.Context, req *csi.CreateVolumeRequest) (string, WithVolumeType(vtype). WithVolumeStatus(zfs.ZFSStatusPending). WithFsType(fstype). + WithQuotaType(quotatype). WithShared(shared). WithCompression(compression).Build() diff --git a/pkg/zfs/zfs_util.go b/pkg/zfs/zfs_util.go index 2c9b331e2..77f59dd3c 100644 --- a/pkg/zfs/zfs_util.go +++ b/pkg/zfs/zfs_util.go @@ -143,7 +143,7 @@ func buildCloneCreateArgs(vol *apis.ZFSVolume) []string { if vol.Spec.VolumeType == VolTypeDataset { if len(vol.Spec.Capacity) != 0 { - quotaProperty := "quota=" + vol.Spec.Capacity + quotaProperty := vol.Spec.QuotaType + "=" + vol.Spec.Capacity ZFSVolArg = append(ZFSVolArg, "-o", quotaProperty) } if len(vol.Spec.RecordSize) != 0 { @@ -151,8 +151,7 @@ func buildCloneCreateArgs(vol *apis.ZFSVolume) []string { ZFSVolArg = append(ZFSVolArg, "-o", recordsizeProperty) } if vol.Spec.ThinProvision == "no" { - reservationProperty := "reservation=" + vol.Spec.Capacity - ZFSVolArg = append(ZFSVolArg, "-o", reservationProperty) + ZFSVolArg = append(ZFSVolArg, "-o", reservationProperty(vol.Spec.QuotaType, vol.Spec.Capacity)) } ZFSVolArg = append(ZFSVolArg, "-o", "mountpoint=legacy") } @@ -216,7 +215,7 @@ func buildDatasetCreateArgs(vol *apis.ZFSVolume) []string { ZFSVolArg = append(ZFSVolArg, ZFSCreateArg) if len(vol.Spec.Capacity) != 0 { - quotaProperty := "quota=" + vol.Spec.Capacity + quotaProperty := vol.Spec.QuotaType + "=" + vol.Spec.Capacity ZFSVolArg = append(ZFSVolArg, "-o", quotaProperty) } if len(vol.Spec.RecordSize) != 0 { @@ -224,8 +223,7 @@ func buildDatasetCreateArgs(vol *apis.ZFSVolume) []string { ZFSVolArg = append(ZFSVolArg, "-o", recordsizeProperty) } if vol.Spec.ThinProvision == "no" { - reservationProperty := "reservation=" + vol.Spec.Capacity - ZFSVolArg = append(ZFSVolArg, "-o", reservationProperty) + ZFSVolArg = append(ZFSVolArg, "-o", reservationProperty(vol.Spec.QuotaType, vol.Spec.Capacity)) } if len(vol.Spec.Dedup) != 0 { dedupProperty := "dedup=" + vol.Spec.Dedup @@ -292,7 +290,7 @@ func buildVolumeResizeArgs(vol *apis.ZFSVolume) []string { ZFSVolArg = append(ZFSVolArg, ZFSSetArg) if vol.Spec.VolumeType == VolTypeDataset { - quotaProperty := "quota=" + vol.Spec.Capacity + quotaProperty := vol.Spec.QuotaType + "=" + vol.Spec.Capacity ZFSVolArg = append(ZFSVolArg, quotaProperty) } else { volsizeProperty := "volsize=" + vol.Spec.Capacity @@ -350,7 +348,7 @@ func buildVolumeRestoreArgs(rstr *apis.ZFSRestore) ([]string, error) { if rstr.VolSpec.VolumeType == VolTypeDataset { if len(rstr.VolSpec.Capacity) != 0 { - ZFSRecvParam += " -o quota=" + rstr.VolSpec.Capacity + ZFSRecvParam += " -o " + rstr.VolSpec.QuotaType + "=" + rstr.VolSpec.Capacity } if len(rstr.VolSpec.RecordSize) != 0 { ZFSRecvParam += " -o recordsize=" + rstr.VolSpec.RecordSize @@ -968,3 +966,12 @@ func decodeListOutput(raw []byte) ([]apis.Pool, error) { } return pools, nil } + +// get the reservation property based on the quota type +func reservationProperty(quotaType string, capacity string) string { + var reservationProperties = map[string]string{ + "quota": "reservation=", + "refquota": "refreservation=", + } + return reservationProperties[quotaType] + capacity +}