fusefrontend: use NsecToTimespec() for Utimens
This fixes a build problem on 32-bit hosts: internal/fusefrontend/file.go:400: cannot use a.Unix() (type int64) as type int32 in assignment internal/fusefrontend/file.go:406: cannot use m.Unix() (type int64) as type int32 in assignment It also enables full nanosecond timestamps for dates after 1970.
This commit is contained in:
parent
fc0de96763
commit
af5441dcd9
@ -388,23 +388,29 @@ func (f *file) GetAttr(a *fuse.Attr) fuse.Status {
|
|||||||
|
|
||||||
const _UTIME_OMIT = ((1 << 30) - 2)
|
const _UTIME_OMIT = ((1 << 30) - 2)
|
||||||
|
|
||||||
|
// utimeToTimespec converts a "time.Time" pointer as passed to Utimens to a
|
||||||
|
// Timespec that can be passed to the utimensat syscall.
|
||||||
|
func utimeToTimespec(t *time.Time) (ts syscall.Timespec) {
|
||||||
|
if t == nil {
|
||||||
|
ts.Nsec = _UTIME_OMIT
|
||||||
|
} else {
|
||||||
|
ts = syscall.NsecToTimespec(t.UnixNano())
|
||||||
|
// For dates before 1970, NsecToTimespec incorrectly returns negative
|
||||||
|
// nanoseconds. Ticket: https://github.com/golang/go/issues/12777
|
||||||
|
if ts.Nsec < 0 {
|
||||||
|
ts.Nsec = 0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return ts
|
||||||
|
}
|
||||||
|
|
||||||
func (f *file) Utimens(a *time.Time, m *time.Time) fuse.Status {
|
func (f *file) Utimens(a *time.Time, m *time.Time) fuse.Status {
|
||||||
f.fdLock.RLock()
|
f.fdLock.RLock()
|
||||||
defer f.fdLock.RUnlock()
|
defer f.fdLock.RUnlock()
|
||||||
|
|
||||||
ts := make([]syscall.Timespec, 2)
|
ts := make([]syscall.Timespec, 2)
|
||||||
|
ts[0] = utimeToTimespec(a)
|
||||||
if a == nil {
|
ts[1] = utimeToTimespec(m)
|
||||||
ts[0].Nsec = _UTIME_OMIT
|
|
||||||
} else {
|
|
||||||
ts[0].Sec = a.Unix()
|
|
||||||
}
|
|
||||||
|
|
||||||
if m == nil {
|
|
||||||
ts[1].Nsec = _UTIME_OMIT
|
|
||||||
} else {
|
|
||||||
ts[1].Sec = m.Unix()
|
|
||||||
}
|
|
||||||
|
|
||||||
fn := fmt.Sprintf("/proc/self/fd/%d", f.fd.Fd())
|
fn := fmt.Sprintf("/proc/self/fd/%d", f.fd.Fd())
|
||||||
err := syscall.UtimesNano(fn, ts)
|
err := syscall.UtimesNano(fn, ts)
|
||||||
|
@ -230,15 +230,18 @@ func (fs *FS) Truncate(path string, offset uint64, context *fuse.Context) (code
|
|||||||
return code
|
return code
|
||||||
}
|
}
|
||||||
|
|
||||||
func (fs *FS) Utimens(path string, Atime *time.Time, Mtime *time.Time, context *fuse.Context) (code fuse.Status) {
|
func (fs *FS) Utimens(path string, a *time.Time, m *time.Time, context *fuse.Context) (code fuse.Status) {
|
||||||
if fs.isFiltered(path) {
|
if fs.isFiltered(path) {
|
||||||
return fuse.EPERM
|
return fuse.EPERM
|
||||||
}
|
}
|
||||||
cPath, err := fs.encryptPath(path)
|
cPath, err := fs.getBackingPath(path)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fuse.ToStatus(err)
|
return fuse.ToStatus(err)
|
||||||
}
|
}
|
||||||
return fs.FileSystem.Utimens(cPath, Atime, Mtime, context)
|
ts := make([]syscall.Timespec, 2)
|
||||||
|
ts[0] = utimeToTimespec(a)
|
||||||
|
ts[1] = utimeToTimespec(m)
|
||||||
|
return fuse.ToStatus(syscall.UtimesNano(cPath, ts))
|
||||||
}
|
}
|
||||||
|
|
||||||
func (fs *FS) StatFs(path string) *fuse.StatfsOut {
|
func (fs *FS) StatFs(path string) *fuse.StatfsOut {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user