can we use unix hardlinks on a mounted windows share?

The ln command can create hard links on the mounted Windows share, but cp -al fails. Is this expected behaviour? I'm trying to save disk space by creating a copy on write style backups using cowdancer, rsync and cp -al.

backupuser@lan0:/mnt/backup/share$ mkdir a
backupuser@lan0:/mnt/backup/share$ touch a/b
backupuser@lan0:/mnt/backup/share$ cp -al a x
cp: cannot create hard link `x/b' to `a/b': No such file or directory
backupuser@lan0:/mnt/backup/share$ mkdir x
mkdir: cannot create directory `x': File exists
backupuser@lan0:/mnt/backup/share$ ln a/b x/b
backupuser@lan0:/mnt/backup/share$ ls -l x
total 0
-rwxr-xr-x 0 backupuser backupuser 0 Dec 23 17:33 b

Update: ln is actually creating a copy and not a real link


Solution 1:

Are you running SAMBA as server? Then look for "unix extensions" in "smb.conf" and enable them.

https://www.samba.org/samba/docs/man/manpages-3/smb.conf.5.html#UNIXEXTENSIONS

With "unix extensions" enabled, SAMBA supports hard links, unix ownership information and mode for files and directories (aka. permissions).

However, this setting is a global setting. Therefore enabling unix extensions affects all shares (which might or might not be what you want).

Solution 2:

I've recently tested this using Windows 10 Pro as the server. My Linux system is running CentOS 7, which as of today ships Samba 4.4.4. Hardlink works well just like on a local file system.

Tests:

/mnt/f/tmp# mkdir a
/mnt/f/tmp# touch a/b
/mnt/f/tmp# cp -al a x
/mnt/f/tmp# stat a/b
  File: ‘a/b’
  Size: 0           Blocks: 0          IO Block: 16384  regular empty file
Device: 28h/40d Inode: 1688849861497214  Links: 2
Access: (0755/-rwxr-xr-x)  Uid: ( 1000/   yanli)   Gid: ( 1000/   yanli)
Context: system_u:object_r:cifs_t:s0
Access: 2017-05-17 14:31:43.564755100 -0700
Modify: 2017-05-17 14:31:43.564755100 -0700
Change: 2017-05-17 14:31:46.571727600 -0700
 Birth: -
/mnt/f/tmp# stat x/b
  File: ‘x/b’
  Size: 0           Blocks: 0          IO Block: 16384  regular empty file
Device: 28h/40d Inode: 1688849861497214  Links: 2
Access: (0755/-rwxr-xr-x)  Uid: ( 1000/   yanli)   Gid: ( 1000/   yanli)
Context: system_u:object_r:cifs_t:s0
Access: 2017-05-17 14:31:43.564755100 -0700
Modify: 2017-05-17 14:31:43.564755100 -0700
Change: 2017-05-17 14:31:46.571727600 -0700
 Birth: -
/mnt/f/tmp# echo something >a/b
/mnt/f/tmp# cat x/b
something
/mnt/f/tmp# mount | grep /mnt/f
//192.168.1.7/f on /mnt/f type cifs (rw,nosuid,nodev,noexec,relatime,vers=1.0,cache=strict,username=redacted,domain=REDACTED,uid=1000,forceuid,gid=1000,forcegid,addr=192.168.1.7,file_mode=0755,dir_mode=0755,nounix,serverino,mapposix,rsize=61440,wsize=65536,echo_interval=60,actimeo=1,user)

As you can see, file a/b and x/b have the same Inode number, indicating that they are hardlinks to the same Inode. Changing the content of one file affects the other file too.

ln works correctly too.

No special option was used to mount the CIFS; every option was default. I didn't do anything special on the Windows side either. It's just a default installation of Windows 10 Pro and a plain shared folder.

What I do not know yet is when this feature was added to CIFS/Samba client/Windows. OP only said "Windows share", so it's not clear what version of Windows/Samba s/he was running. I hope my answer can help those who have trouble with creating hardlinks on CIFS mounted share backed by a Windows server; you may solve the problem by upgrading to Windows 10 Pro and at least Samba 4.4.4 (CentOS is not known for shipping the shiniest and latest code).