@node Новости
@section Новости
+@node Релиз 5.1.2
+@subsection Релиз 5.1.2
+@itemize
+
+@item
+Явная синхронизация (fsync) директорий для гарантированного
+переименования файлов.
+
+@end itemize
+
@node Релиз 5.1.1
@subsection Релиз 5.1.1
@itemize
See also this page @ref{Новости, on russian}.
+@node Release 5.1.2
+@section Release 5.1.2
+@itemize
+
+@item
+Explicit directories fsync-ing for guaranteed files renaming.
+
+@end itemize
+
@node Release 5.1.1
@section Release 5.1.1
@itemize
if err = os.Rename(tmp.Name(), dstPath); err != nil {
log.Fatalln("Error during renaming:", err)
}
+ if err = nncp.DirSync(selfPath); err != nil {
+ log.Fatalln("Error during syncing:", err)
+ }
}
}
ctx.LogI("nncp-bundle", nncp.SdsAdd(sds, nncp.SDS{
if err = os.Rename(tmp.Name(), dstPath); err != nil {
log.Fatalln(err)
}
+ if err = nncp.DirSync(mainDir); err != nil {
+ log.Fatalln(err)
+ }
ctx.LogI("nncp-reass", nncp.SDS{"path": path}, "done")
return !hasErrors
}
isBad = true
continue
}
+ if err = nncp.DirSync(dstPath); err != nil {
+ ctx.LogE("nncp-xfer", nncp.SdsAdd(sds, nncp.SDS{"err": err}), "sync")
+ isBad = true
+ continue
+ }
os.Remove(filepath.Join(dstPath, pktName+".part"))
delete(sds, "tmp")
ctx.LogI("nncp-xfer", nncp.SdsAdd(sds, nncp.SDS{
sdsp["xx"] = string(TRx)
sdsp["hash"] = ToBase32(file.Hash[:])
sdsp["size"] = strconv.Itoa(len(file.Payload))
- filePath := filepath.Join(
+ dirToSync := filepath.Join(
state.Ctx.Spool,
state.Node.Id.String(),
string(TRx),
- ToBase32(file.Hash[:]),
)
+ filePath := filepath.Join(dirToSync, ToBase32(file.Hash[:]))
state.Ctx.LogD("sp-file", sdsp, "opening part")
fd, err := os.OpenFile(
filePath+PartSuffix,
return
}
state.Ctx.LogI("sp-done", SdsAdd(sdsp, SDS{"xx": string(TRx)}), "")
- os.Rename(filePath+PartSuffix, filePath)
+ if err = os.Rename(filePath+PartSuffix, filePath); err != nil {
+ state.Ctx.LogE("sp-file", SdsAdd(sdsp, SDS{"err": err}), "rename")
+ return
+ }
+ if err = DirSync(dirToSync); err != nil {
+ state.Ctx.LogE("sp-file", SdsAdd(sdsp, SDS{"err": err}), "sync")
+ return
+ }
state.Lock()
delete(state.infosTheir, *file.Hash)
state.Unlock()
os.Remove(tmp.Fd.Name())
}
+func DirSync(dirPath string) error {
+ fd, err := os.Open(dirPath)
+ if err != nil {
+ return err
+ }
+ err = fd.Sync()
+ if err != nil {
+ fd.Close()
+ return err
+ }
+ return fd.Close()
+}
+
func (tmp *TmpFileWHash) Commit(dir string) error {
var err error
if err = os.MkdirAll(dir, os.FileMode(0777)); err != nil {
tmp.Fd.Close()
checksum := ToBase32(tmp.Hsh.Sum(nil))
tmp.ctx.LogD("tmp", SDS{"src": tmp.Fd.Name(), "dst": checksum}, "commit")
- return os.Rename(tmp.Fd.Name(), filepath.Join(dir, checksum))
+ if err = os.Rename(tmp.Fd.Name(), filepath.Join(dir, checksum)); err != nil {
+ return err
+ }
+ return DirSync(dir)
}
ctx.LogE("rx", SdsAdd(sds, SDS{"err": err}), "rename")
isBad = true
}
+ if err = DirSync(*incoming); err != nil {
+ ctx.LogE("rx", SdsAdd(sds, SDS{"err": err}), "sync")
+ isBad = true
+ }
delete(sds, "tmp")
}
ctx.LogI("rx", sds, "")