[#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:
parent
694d888219
commit
f564430b90
2 changed files with 32 additions and 2 deletions
|
@ -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
|
||||||
}
|
}
|
||||||
|
|
|
@ -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
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in a new issue