[#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 Depth uint64
DirNameLen int DirNameLen int
noSync bool
readOnly bool readOnly bool
} }
@ -238,16 +239,39 @@ func (t *FSTree) Put(prm common.PutPrm) (common.PutRes, error) {
prm.RawData = t.Compress(prm.RawData) prm.RawData = t.Compress(prm.RawData)
} }
err := os.WriteFile(p, prm.RawData, t.Permissions) err := t.writeFile(p, prm.RawData)
if err != nil { if err != nil {
var pe *fs.PathError var pe *fs.PathError
if errors.As(err, &pe) && pe.Err == syscall.ENOSPC { if errors.As(err, &pe) && pe.Err == syscall.ENOSPC {
err = common.ErrNoSpace err = common.ErrNoSpace
} }
} }
return common.PutRes{StorageID: []byte{}}, err 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. // PutStream puts executes handler on a file opened for write.
func (t *FSTree) PutStream(addr oid.Address, handler func(*os.File) error) error { func (t *FSTree) PutStream(addr oid.Address, handler func(*os.File) error) error {
if t.readOnly { if t.readOnly {
@ -260,7 +284,7 @@ func (t *FSTree) PutStream(addr oid.Address, handler func(*os.File) error) error
return err 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 { if err != nil {
return err return err
} }

View file

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