diff --git a/internal/rbd/rbd_util.go b/internal/rbd/rbd_util.go index 4d60c5ad2..5d6df381e 100644 --- a/internal/rbd/rbd_util.go +++ b/internal/rbd/rbd_util.go @@ -299,6 +299,15 @@ func (rv *rbdVolume) open() (*librbd.Image, error) { 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) + // We do not want to call discard, we really want to write zeros to get + // the allocation. This sets the option for the re-used connection, and + // all subsequent images that are opened. That is not a problem, as + // this is the only place images get written. + err := rv.conn.DisableDiscardOnZeroedWriteSame() + if err != nil { + return err + } + image, err := rv.open() if err != nil { return err diff --git a/internal/util/connection.go b/internal/util/connection.go index 713e1ab43..1917e2dac 100644 --- a/internal/util/connection.go +++ b/internal/util/connection.go @@ -32,6 +32,8 @@ type ClusterConnection struct { // FIXME: temporary reference for credentials. Remove this when go-ceph // is used for operations. Creds *Credentials + + discardOnZeroedWriteSameDisabled bool } var ( @@ -92,3 +94,22 @@ func (cc *ClusterConnection) GetFSAdmin() (*ca.FSAdmin, error) { return ca.NewFromConn(cc.conn), nil } + +// DisableDiscardOnZeroedWriteSame enables the +// `rbd_discard_on_zeroed_write_same` option in the cluster connection, so that +// writing zero blocks of data are actual writes on the OSDs (doing +// allocations) and not discard calls. This makes writes much slower, but +// enables the option to do thick-provisioning. +func (cc *ClusterConnection) DisableDiscardOnZeroedWriteSame() error { + if cc.discardOnZeroedWriteSameDisabled { + return nil + } + + err := cc.conn.SetConfigOption("rbd_discard_on_zeroed_write_same", "false") + if err != nil { + return err + } + + cc.discardOnZeroedWriteSameDisabled = true + return nil +}