From f564430b902f08fe30e36ea0a23fa339e5e5c25b Mon Sep 17 00:00:00 2001 From: Evgenii Stratonikov Date: Fri, 28 Oct 2022 12:57:36 +0300 Subject: [PATCH] [#1992] fstree: Allow working in SYNC mode Make O_SYNC the default and allow to opt-out explicitly. Signed-off-by: Evgenii Stratonikov --- .../blobstor/fstree/fstree.go | 28 +++++++++++++++++-- .../blobstor/fstree/option.go | 6 ++++ 2 files changed, 32 insertions(+), 2 deletions(-) diff --git a/pkg/local_object_storage/blobstor/fstree/fstree.go b/pkg/local_object_storage/blobstor/fstree/fstree.go index e3326743..9254095f 100644 --- a/pkg/local_object_storage/blobstor/fstree/fstree.go +++ b/pkg/local_object_storage/blobstor/fstree/fstree.go @@ -28,6 +28,7 @@ type FSTree struct { Depth uint64 DirNameLen int + noSync bool readOnly bool } @@ -238,16 +239,39 @@ func (t *FSTree) Put(prm common.PutPrm) (common.PutRes, error) { prm.RawData = t.Compress(prm.RawData) } - err := os.WriteFile(p, prm.RawData, t.Permissions) + err := t.writeFile(p, prm.RawData) if err != nil { var pe *fs.PathError if errors.As(err, &pe) && pe.Err == syscall.ENOSPC { err = common.ErrNoSpace } } + return common.PutRes{StorageID: []byte{}}, err } +func (t *FSTree) writeFlags() int { + flags := os.O_WRONLY | os.O_CREATE | os.O_TRUNC + if t.noSync { + return flags + } + return flags | os.O_SYNC +} + +// writeFile writes data to a file with path p. +// The code is copied from `os.WriteFile` with minor corrections for flags. +func (t *FSTree) writeFile(p string, data []byte) error { + f, err := os.OpenFile(p, t.writeFlags(), t.Permissions) + if err != nil { + return err + } + _, err = f.Write(data) + if err1 := f.Close(); err1 != nil && err == nil { + err = err1 + } + return err +} + // PutStream puts executes handler on a file opened for write. func (t *FSTree) PutStream(addr oid.Address, handler func(*os.File) error) error { if t.readOnly { @@ -260,7 +284,7 @@ func (t *FSTree) PutStream(addr oid.Address, handler func(*os.File) error) error return err } - f, err := os.OpenFile(p, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, t.Permissions) + f, err := os.OpenFile(p, t.writeFlags(), t.Permissions) if err != nil { return err } diff --git a/pkg/local_object_storage/blobstor/fstree/option.go b/pkg/local_object_storage/blobstor/fstree/option.go index 2c2e55bd..07e54744 100644 --- a/pkg/local_object_storage/blobstor/fstree/option.go +++ b/pkg/local_object_storage/blobstor/fstree/option.go @@ -29,3 +29,9 @@ func WithPath(p string) Option { f.RootPath = p } } + +func WithNoSync(noSync bool) Option { + return func(f *FSTree) { + f.noSync = noSync + } +}