3

I have the feeling that I cannot modify the date of symlinks on bindfs. See the following transcript of what I tried.

On EXT4:

nailor@needle:~$ mkdir /tmp/ex
nailor@needle:~$ cd /tmp/ex
nailor@needle:/tmp/ex$ touch realfile  
nailor@needle:/tmp/ex$ ln -s realfile linkfile
nailor@needle:/tmp/ex$ stat realfile linkfile
  File: `realfile'
  Size: 0           Blocks: 0          IO Block: 4096   regular empty file
Device: 801h/2049d  Inode: 22678377    Links: 1
Access: (0644/-rw-r--r--)  Uid: ( 1000/  nailor)   Gid: ( 1000/  nailor)
Access: 2013-09-09 00:46:15.356004837 +0200
Modify: 2013-09-09 00:46:15.356004837 +0200
Change: 2013-09-09 00:46:15.356004837 +0200
 Birth: -
  File: `linkfile' -> `realfile'
  Size: 8           Blocks: 0          IO Block: 4096   symbolic link
Device: 801h/2049d  Inode: 22678380    Links: 1
Access: (0777/lrwxrwxrwx)  Uid: ( 1000/  nailor)   Gid: ( 1000/  nailor)
Access: 2013-09-09 00:46:34.299766676 +0200
Modify: 2013-09-09 00:46:27.227855586 +0200
Change: 2013-09-09 00:46:27.227855586 +0200
 Birth: -
nailor@needle:/tmp/ex$ touch -h realfile linkfile
nailor@needle:/tmp/ex$ stat realfile linkfile    
  File: `realfile'
  Size: 0           Blocks: 0          IO Block: 4096   regular empty file
Device: 801h/2049d  Inode: 22678377    Links: 1
Access: (0644/-rw-r--r--)  Uid: ( 1000/  nailor)   Gid: ( 1000/  nailor)
Access: 2013-09-09 00:46:46.931607877 +0200
Modify: 2013-09-09 00:46:46.931607877 +0200
Change: 2013-09-09 00:46:46.931607877 +0200
 Birth: -
  File: `linkfile' -> `realfile'
  Size: 8           Blocks: 0          IO Block: 4096   symbolic link
Device: 801h/2049d  Inode: 22678380    Links: 1
Access: (0777/lrwxrwxrwx)  Uid: ( 1000/  nailor)   Gid: ( 1000/  nailor)
Access: 2013-09-09 00:46:49.899570563 +0200
Modify: 2013-09-09 00:46:46.931607877 +0200
Change: 2013-09-09 00:46:46.931607877 +0200
 Birth: -

On bindfs:

nailor@needle:/tmp/ex$ mkdir sub      
nailor@needle:/tmp/ex$ bindfs -n . sub
nailor@needle:/tmp/ex$ cd sub
nailor@needle:/tmp/ex/sub$ touch -h realfile linkfile 
nailor@needle:/tmp/ex/sub$ stat realfile linkfile 
  File: `realfile'
  Size: 0           Blocks: 0          IO Block: 4096   regular empty file
Device: 17h/23d Inode: 2           Links: 1
Access: (0644/-rw-r--r--)  Uid: ( 1000/  nailor)   Gid: ( 1000/  nailor)
Access: 2013-09-09 00:47:34.000000000 +0200
Modify: 2013-09-09 00:47:34.000000000 +0200
Change: 2013-09-09 00:47:34.755006803 +0200
 Birth: -
  File: `linkfile' -> `realfile'
  Size: 8           Blocks: 0          IO Block: 4096   symbolic link
Device: 17h/23d Inode: 3           Links: 1
Access: (0777/lrwxrwxrwx)  Uid: ( 1000/  nailor)   Gid: ( 1000/  nailor)
Access: 2013-09-09 00:46:49.899570563 +0200
Modify: 2013-09-09 00:46:46.931607877 +0200
Change: 2013-09-09 00:46:46.931607877 +0200
 Birth: -

As you can see, the times for the symlink did not change on bindfs. This is a problem with e.g. rsync, because this way I get:

rsync: failed to set times on "link1": No such file or directory (2)
rsync: failed to set times on "link2": No such file or directory (2)
...

I found this to be a known problem with sshfs ( http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=640038 ) but found nothing mentioning bindfs. Now I am wondering if there is any such mentioning and/or and explanation for the missing functionality and/or an answer if this affect fuse in general...

1
  • On second thoughts, I think the bug is in bindfs, see my updated answer. I haven't dug very deeply however, so my analysis could be wrong. Commented Sep 9, 2013 at 9:34

2 Answers 2

5

Filesystems where you can't change the date of a symlink are common. This in itself is not a bug of bindfs or sshfs.

Rsync is designed to cope with that. It ignores failures to change the time and other metadata of symbolic links if the underlying filesystem doesn't support it.

Under Linux, rsync calls utimensat with the AT_SYMLINK_NOFOLLOW flag to change the times of the symbolic link. As far as I can tell, the problem is that the FUSE API has no corresponding flag for utimens (or utime), so the filesystem implementation only sees a request to change the time and no indication of whether to follow the symbolic link or not. Lacking any specific indication, both bindfs and sshfs act in a backward-compatible way: they modify the target of the symbolic link. For a broken symbolic link, this results in an ENOENT error.

At first glance, I thought this was a bug in FUSE: since FUSE is unable to pass the AT_SYMLINK_NOFOLLOW flag, it should return an error (EINVAL, or ENOTSUP). However, from a cursory reading of the Linux VFS code, it looks like the filesystem-specific code is invoked either on the symbolic link or on its target, and should therefore never follow any symbolic link. This makes perfect sense: the target of the symbolic link may be on a different filesystem.

So I think this is a bug in bindfs and sshfs (and probably in many other FUSE filesystems): if instructed to change the metadata of a symbolic link, they should only affect that symbolic link, or return an error if the requested change is not possible.

1
  • (or ENOTSUP). Commented Sep 9, 2013 at 8:11
2

This bug is now fixed in bindfs version 1.12.3.

Gilles's answer explains the bug superbly.

1
  • Thank you! I wasn't sure my analysis was correct, and never found the time to dig deeper for a bug report. Commented Sep 23, 2013 at 21:27

You must log in to answer this question.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.