This is the mail archive of the cygwin mailing list for the Cygwin project.

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

link(2) on NFS

I've noticed that link(2) is inconsistent:

$ cd /cygdrive/c   # c:\ is local NTFS
$ touch f
$ link f g      # success
$ ls -i1 f g
3301138526862583480 f
3301138526862583480 g

This works nicely.

$ cd /cygdrive/m/eblake/devel  # m:\ is an MVFS mounted drive
$ touch f
$ link f g
$ ls -i1 f g      # Oops - distinct copies
11136640032873583774 f
11136640032873583775 g
$ rm g
$ strace link f g
13426 7735180 [main] link 1980 fhandler_disk_file::link: FS doesn't support hard
 links: Copy file
89316 7824496 [main] link 1980 fhandler_base::close: closing '/cygdrive/m/eblake/devel/f' handle 0x2FC
 4523 7829019 [main] link 1980 fhandler_base::open: (m:\eblake\devel\g, 0x110000)
 7870 7836889 [main] link 1980 fhandler_base::set_flags: flags 0x110000, supplied_bin 0x10000
  148 7837037 [main] link 1980 fhandler_base::set_flags: O_TEXT/O_BINARY set in flags 0x10000
   65 7837102 [main] link 1980 fhandler_base::set_flags: filemode set to binary
   62 7837164 [main] link 1980 fhandler_base::open: 0 = NtCreateFile (0x2EC, 20100, m:\eblake\devel\g, io, NULL, 0, 7, 1, 4400, NULL, 0)
   64 7837228 [main] link 1980 fhandler_base::open: 1 = fhandler_base::open (m:\eblake\devel\g, 0x110000)
   71 7837299 [main] link 1980 fhandler_base::open_fs: 1 = fhandler_disk_file::open (m:\eblake\devel\g, 0x10000)
   81 7837380 [main] link 1980 fhandler_base::close: closing '/cygdrive/m/eblake/devel/g' handle 0x2EC
 5759 7843139 [main] link 1980 link: 0 = link (f, g)

MVFS supports hard links when accessed under Unix, but apparently Windows doesn't know how do create hard links on MVFS.  The approach taken by cygwin of creating a distinct copy satisfies the common need of just reproducing the file contents, but it consumes extra space and breaks atomicity algorithms that assume a successful link(2) means a shared inode and that edits to one file are visible in the other.  It would almost be nicer if link(2) on an inferior filesystem (including FAT under Windows 9x) would just fail rather than violate POSIX semantics by creating a copy.  Portable programs that only need the copy semantics, and don't care about the inode sharing semantics, such as autoconf or automake, already know how to fall back to `ln -s' or `cp -p' as alternatives when `ln' is not successful.

$ cd /cygdrive/u   # u:\ is an NFS mounted drive on Unix
$ touch f
$ link f g
link: cannot create link `g' to `f': No such file or directory
$ strace link f g
  215 10775168 [main] link 2448 fhandler_disk_file::link: CreateHardLinkA failed
   72 10775240 [main] link 2448 seterrno_from_win_error: /netrel/src/cygwin-1.5.16-1/winsup/cygwin/ windows error 123
   67 10775307 [main] link 2448 geterrno_from_win_error: windows error 123 == errno 2
   61 10775368 [main] link 2448 fhandler_base::close: closing '/cygdrive/u/f' handle 0x304
  858 10776226 [main] link 2448 link: -1 = link (f, g)

Windows Error 123 is ERROR_INVALID_NAME, so it appears that Windows can't create the link on NFS, even though the underlying file system supports it.  But the error message is sure confusing - link(1) sees ENOENT and reports that `f' does not exist, which is wrong.  It would be nicer if link(2) could map this particular error to EMLINK or ENOSYS.

Eric Blake

Unsubscribe info:
Problem reports:

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]