Commit 1e27f6dd authored by Han-Wen Nienhuys's avatar Han-Wen Nienhuys Committed by Han-Wen Nienhuys

fs: fix setting timestamps on broken symlinks

Use UtimesNanoAt with AT_SYMLINK_NOFOLLOW. Add
PosixTest/SetattrSymlink to test this.

Change-Id: Ia3a00ad75afd1ba255965025f63fd047662885ec
parent 698fe30b
......@@ -403,20 +403,23 @@ func (n *LoopbackNode) Setattr(ctx context.Context, f FileHandle, in *fuse.SetAt
atime, aok := in.GetATime()
if mok || aok {
ap := &atime
mp := &mtime
if !aok {
ap = nil
ta := unix.Timespec{Nsec: unix.UTIME_OMIT}
tm := unix.Timespec{Nsec: unix.UTIME_OMIT}
var err error
if aok {
ta, err = unix.TimeToTimespec(atime)
if err != nil {
return ToErrno(err)
}
}
if !mok {
mp = nil
if mok {
tm, err = unix.TimeToTimespec(mtime)
if err != nil {
return ToErrno(err)
}
}
var ts [2]syscall.Timespec
ts[0] = fuse.UtimeToTimespec(ap)
ts[1] = fuse.UtimeToTimespec(mp)
if err := syscall.UtimesNano(p, ts[:]); err != nil {
ts := []unix.Timespec{ta, tm}
if err := unix.UtimesNanoAt(unix.AT_FDCWD, p, ts, unix.AT_SYMLINK_NOFOLLOW); err != nil {
return ToErrno(err)
}
}
......
......@@ -48,6 +48,32 @@ var All = map[string]func(*testing.T, string){
"DirSeek": DirSeek,
"FcntlFlockSetLk": FcntlFlockSetLk,
"FcntlFlockLocksFile": FcntlFlockLocksFile,
"SetattrSymlink": SetattrSymlink,
}
func SetattrSymlink(t *testing.T, mnt string) {
l := filepath.Join(mnt, "link")
if err := os.Symlink("doesnotexist", l); err != nil {
t.Fatalf("symlink: %v", err)
}
tvs := []unix.Timeval{
{Sec: 42, Usec: 1},
{Sec: 43, Usec: 2},
}
if err := unix.Lutimes(l, tvs); err != nil {
t.Fatalf("Lutimes: %v", err)
}
var st unix.Stat_t
if err := unix.Lstat(l, &st); err != nil {
t.Fatalf("Lstat: %v", err)
}
if st.Mtim.Sec != 43 {
// Can't check atime; it's hard to prevent implicit readlink calls.
t.Fatalf("got mtime %v, want 43", st.Mtim)
}
}
func DirectIO(t *testing.T, mnt string) {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment