m/n/kubernetes: set PV inode quota relative to capacity
This removes the hardcoded 100k inode limit which is very low for large
PVs in favor of a scaled value dependent on its capacity. This
technically allows overcommit as the inode space is not accounted for on
the capacity side, but this was already the case before, just with a
static limit.
Change-Id: I48816cd904127397907c1372e7cbb4b9b5ea60f2
Reviewed-on: https://review.monogon.dev/c/monogon/+/3339
Tested-by: Jenkins CI
Reviewed-by: Serge Bazanski <serge@monogon.tech>
diff --git a/metropolis/node/kubernetes/csi.go b/metropolis/node/kubernetes/csi.go
index 6f6c3a3..dfbd48c 100644
--- a/metropolis/node/kubernetes/csi.go
+++ b/metropolis/node/kubernetes/csi.go
@@ -219,7 +219,7 @@
}
return &csi.NodeExpandVolumeResponse{CapacityBytes: req.CapacityRange.LimitBytes}, nil
}
- if err := fsquota.SetQuota(req.VolumePath, uint64(req.CapacityRange.LimitBytes), 0); err != nil {
+ if err := fsquota.SetQuota(req.VolumePath, uint64(req.CapacityRange.LimitBytes), uint64(req.CapacityRange.LimitBytes)/inodeCapacityRatio); err != nil {
return nil, status.Errorf(codes.Unavailable, "failed to update quota: %v", err)
}
return &csi.NodeExpandVolumeResponse{CapacityBytes: req.CapacityRange.LimitBytes}, nil
diff --git a/metropolis/node/kubernetes/provisioner.go b/metropolis/node/kubernetes/provisioner.go
index 923302e..46fd908 100644
--- a/metropolis/node/kubernetes/provisioner.go
+++ b/metropolis/node/kubernetes/provisioner.go
@@ -45,6 +45,11 @@
"source.monogon.dev/osbase/supervisor"
)
+// inodeCapacityRatio describes the ratio between the byte capacity of a volume
+// and its inode capacity. One inode on XFS is 512 bytes and by default 25%
+// (1/4) of capacity can be used for metadata.
+const inodeCapacityRatio = 4 * 512
+
// ONCHANGE(//metropolis/node/kubernetes/reconciler:resources_csi.go): needs to
// match csiProvisionerServerName declared.
const csiProvisionerServerName = "dev.monogon.metropolis.vfs"
@@ -293,7 +298,7 @@
if len(files) > 0 {
return errors.New("newly-created volume already contains data, bailing")
}
- if err := fsquota.SetQuota(volumePath, uint64(capacity), 100000); err != nil {
+ if err := fsquota.SetQuota(volumePath, uint64(capacity), uint64(capacity)/inodeCapacityRatio); err != nil {
return fmt.Errorf("failed to update quota: %w", err)
}
case v1.PersistentVolumeBlock: