[#1992] fstree: Allow working in SYNC mode

Make O_SYNC the default and allow to opt-out explicitly.

Signed-off-by: Evgenii Stratonikov <evgeniy@morphbits.ru>
This commit is contained in:
Evgenii Stratonikov 2022-10-28 12:57:36 +03:00 committed by fyrchik
parent 694d888219
commit 0de9efa685
2 changed files with 32 additions and 2 deletions

View file

@ -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
}

View file

@ -29,3 +29,9 @@ func WithPath(p string) Option {
f.RootPath = p
}
}
func WithNoSync(noSync bool) Option {
return func(f *FSTree) {
f.noSync = noSync
}
}