diff options
| author | Jakob Unterwurzacher | 2016-08-09 22:18:46 +0200 | 
|---|---|---|
| committer | Jakob Unterwurzacher | 2016-08-09 22:18:46 +0200 | 
| commit | af5441dcd9033e81da43ab77887a7b5aac693ab6 (patch) | |
| tree | 54d8efea78ebc56d8f8f62ffc20f527d5adc4a05 /internal | |
| parent | fc0de96763280d24cfb30646c82efddb18cbb59d (diff) | |
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.
Diffstat (limited to 'internal')
| -rw-r--r-- | internal/fusefrontend/file.go | 30 | ||||
| -rw-r--r-- | internal/fusefrontend/fs.go | 9 | 
2 files changed, 24 insertions, 15 deletions
| diff --git a/internal/fusefrontend/file.go b/internal/fusefrontend/file.go index b9bb2c9..61b1e55 100644 --- a/internal/fusefrontend/file.go +++ b/internal/fusefrontend/file.go @@ -388,23 +388,29 @@ func (f *file) GetAttr(a *fuse.Attr) fuse.Status {  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 {  	f.fdLock.RLock()  	defer f.fdLock.RUnlock()  	ts := make([]syscall.Timespec, 2) - -	if a == nil { -		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() -	} +	ts[0] = utimeToTimespec(a) +	ts[1] = utimeToTimespec(m)  	fn := fmt.Sprintf("/proc/self/fd/%d", f.fd.Fd())  	err := syscall.UtimesNano(fn, ts) diff --git a/internal/fusefrontend/fs.go b/internal/fusefrontend/fs.go index 5367622..1219479 100644 --- a/internal/fusefrontend/fs.go +++ b/internal/fusefrontend/fs.go @@ -230,15 +230,18 @@ func (fs *FS) Truncate(path string, offset uint64, context *fuse.Context) (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) {  		return fuse.EPERM  	} -	cPath, err := fs.encryptPath(path) +	cPath, err := fs.getBackingPath(path)  	if err != nil {  		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 { | 
