Mercurial > public > mercurial-scm > hg-stable
comparison mercurial/util.py @ 31581:e506e461c7a9
util: disable hardlink for copyfile if fstype is outside a whitelist
Since osutil.getfstype is available, use it to detect filesystem types. The
whitelist currently includes common local filesystems on Linux where they
should have good hardlink support. We may add new filesystems for other
platforms later.
author | Jun Wu <quark@fb.com> |
---|---|
date | Sun, 12 Mar 2017 00:23:07 -0800 |
parents | 55c6788c54e2 |
children | e7a02e9ad162 |
comparison
equal
deleted
inserted
replaced
31580:a8e55d6f1d67 | 31581:e506e461c7a9 |
---|---|
1058 # Hardlinks are problematic on CIFS, do not allow hardlinks | 1058 # Hardlinks are problematic on CIFS, do not allow hardlinks |
1059 # until we find a way to work around it cleanly (issue4546). | 1059 # until we find a way to work around it cleanly (issue4546). |
1060 # This is a variable so extensions can opt-in to using them. | 1060 # This is a variable so extensions can opt-in to using them. |
1061 allowhardlinks = False | 1061 allowhardlinks = False |
1062 | 1062 |
1063 # a whilelist of known filesystems where hardlink works reliably | |
1064 _hardlinkfswhitelist = set([ | |
1065 'btrfs', | |
1066 'ext2', | |
1067 'ext3', | |
1068 'ext4', | |
1069 'jfs', | |
1070 'reiserfs', | |
1071 'tmpfs', | |
1072 'xfs', | |
1073 ]) | |
1074 | |
1063 def copyfile(src, dest, hardlink=False, copystat=False, checkambig=False): | 1075 def copyfile(src, dest, hardlink=False, copystat=False, checkambig=False): |
1064 '''copy a file, preserving mode and optionally other stat info like | 1076 '''copy a file, preserving mode and optionally other stat info like |
1065 atime/mtime | 1077 atime/mtime |
1066 | 1078 |
1067 checkambig argument is used with filestat, and is useful only if | 1079 checkambig argument is used with filestat, and is useful only if |
1074 oldstat = None | 1086 oldstat = None |
1075 if os.path.lexists(dest): | 1087 if os.path.lexists(dest): |
1076 if checkambig: | 1088 if checkambig: |
1077 oldstat = checkambig and filestat(dest) | 1089 oldstat = checkambig and filestat(dest) |
1078 unlink(dest) | 1090 unlink(dest) |
1091 if hardlink: | |
1092 # Hardlinks are problematic on CIFS (issue4546), do not allow hardlinks | |
1093 # unless we are confident that dest is on a whitelisted filesystem. | |
1094 destdir = os.path.dirname(dest) | |
1095 fstype = getattr(osutil, 'getfstype', lambda x: None)(destdir) | |
1096 if fstype not in _hardlinkfswhitelist: | |
1097 hardlink = False | |
1079 if allowhardlinks and hardlink: | 1098 if allowhardlinks and hardlink: |
1080 try: | 1099 try: |
1081 oslink(src, dest) | 1100 oslink(src, dest) |
1082 return | 1101 return |
1083 except (IOError, OSError): | 1102 except (IOError, OSError): |