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/fhandler_disk_file.cc:740 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:      http://cygwin.com/ml/#unsubscribe-simple
Problem reports:       http://cygwin.com/problems.html
Documentation:         http://cygwin.com/docs.html
FAQ:                   http://cygwin.com/faq/

Reply via email to