X-Git-Url: http://www.git.cypherpunks.ru/?p=goredo.git;a=blobdiff_plain;f=inode.go;h=51c97b3572bd37fa8eff995caba187607714464b;hp=8ec6b9e38c628d65650c2f302b7270091cdfd072;hb=2cea0c64b5a0240bfe6746a98a5b350812edb96d;hpb=8db620bb85d5db033728ba0bc154a373aacf0e34 diff --git a/inode.go b/inode.go index 8ec6b9e..51c97b3 100644 --- a/inode.go +++ b/inode.go @@ -28,20 +28,45 @@ import ( "golang.org/x/sys/unix" ) -const EnvInodeNoTrust = "REDO_INODE_NO_TRUST" +type InodeTrustType int -var InodeTrust = false +//go:generate stringer -type=InodeTrustType +const ( + EnvInodeTrust = "REDO_INODE_TRUST" + + InodeTrustNone InodeTrustType = iota + InodeTrustCtime + InodeTrustMtime +) + +var InodeTrust InodeTrustType type Inode struct { Size int64 CtimeSec int64 CtimeNsec int64 + MtimeSec int64 + MtimeNsec int64 } func (our *Inode) Equals(their *Inode) bool { - return (our.Size == their.Size) && - (our.CtimeSec == their.CtimeSec) && - (our.CtimeNsec == their.CtimeNsec) + if our.Size != their.Size { + return false + } + switch InodeTrust { + case InodeTrustCtime: + if our.CtimeSec != their.CtimeSec || our.CtimeNsec != their.CtimeNsec { + return false + } + case InodeTrustMtime: + if our.MtimeSec == 0 || our.MtimeNsec == 0 { + return false + } + if our.MtimeSec != their.MtimeSec || our.MtimeNsec != their.MtimeNsec { + return false + } + } + return true } func (inode *Inode) RecfileFields() []recfile.Field { @@ -49,6 +74,8 @@ func (inode *Inode) RecfileFields() []recfile.Field { {Name: "Size", Value: strconv.FormatInt(inode.Size, 10)}, {Name: "CtimeSec", Value: strconv.FormatInt(inode.CtimeSec, 10)}, {Name: "CtimeNsec", Value: strconv.FormatInt(inode.CtimeNsec, 10)}, + {Name: "MtimeSec", Value: strconv.FormatInt(inode.MtimeSec, 10)}, + {Name: "MtimeNsec", Value: strconv.FormatInt(inode.MtimeNsec, 10)}, } } @@ -63,14 +90,22 @@ func inodeFromFile(fd *os.File) (*Inode, error) { if err != nil { return nil, err } - sec, nsec := stat.Ctim.Unix() - return &Inode{Size: fi.Size(), CtimeSec: sec, CtimeNsec: nsec}, nil + ctimeSec, ctimeNsec := stat.Ctim.Unix() + mtimeSec := fi.ModTime().Unix() + mtimeNsec := fi.ModTime().UnixNano() + return &Inode{ + Size: fi.Size(), + CtimeSec: ctimeSec, CtimeNsec: ctimeNsec, + MtimeSec: mtimeSec, MtimeNsec: mtimeNsec, + }, nil } func inodeFromRec(m map[string]string) (*Inode, error) { size := m["Size"] ctimeSec := m["CtimeSec"] ctimeNsec := m["CtimeNsec"] + mtimeSec := m["MtimeSec"] + mtimeNsec := m["MtimeNsec"] if size == "" { return nil, errors.New("Size is missing") } @@ -94,5 +129,18 @@ func inodeFromRec(m map[string]string) (*Inode, error) { if err != nil { return nil, err } + if mtimeSec != "" { + if mtimeNsec == "" { + return nil, errors.New("MtimeNsec is missing") + } + inode.MtimeSec, err = strconv.ParseInt(mtimeSec, 10, 64) + if err != nil { + return nil, err + } + inode.MtimeNsec, err = strconv.ParseInt(mtimeNsec, 10, 64) + if err != nil { + return nil, err + } + } return &inode, nil }