Skip to content

Commit dafb5ee

Browse files
committed
RF: Precompute CIFS table to minimize overhead
Only check if symlinks might be tried
1 parent 0d5359d commit dafb5ee

File tree

1 file changed

+33
-12
lines changed

1 file changed

+33
-12
lines changed

nipype/utils/filemanip.py

Lines changed: 33 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -238,25 +238,46 @@ def hash_timestamp(afile):
238238
return md5hex
239239

240240

241-
def _on_cifs(fname):
242-
""" Checks whether a PATH is on a CIFS filesystem mounted in a POSIX
243-
host (i.e., has the "mount" command).
241+
def _generate_cifs_table():
242+
"""Construct a reverse-length ordered list of mount points that
243+
fall under a CIFS mount.
244244
245-
CIFS shares are how Docker mounts Windows host directories into containers.
246-
CIFS has partial support for symlinks that can break, causing misleading
247-
errors, so this test is used to disable them on such systems.
245+
This precomputation allows efficient checking for whether a given path
246+
would be on a CIFS filesystem.
247+
248+
On systems without a ``mount`` command, or with no CIFS mounts, returns an
249+
empty list.
248250
"""
249251
exit_code, output = subprocess.getstatusoutput("mount")
250252
# Not POSIX
251253
if exit_code != 0:
252-
return False
254+
return []
253255

254256
# (path, fstype) tuples, sorted by path length (longest first)
255-
paths_types = sorted((line.split()[2:5:2] for line in output.splitlines()),
256-
key=lambda x: len(x[0]),
257-
reverse=True)
257+
mount_info = sorted((line.split()[2:5:2] for line in output.splitlines()),
258+
key=lambda x: len(x[0]),
259+
reverse=True)
260+
cifs_paths = [path for path, fstype in mount_info if fstype == 'cifs']
261+
if cifs_paths == []:
262+
return []
263+
264+
return [mount for mount in mount_info
265+
if any(mount[0].startswith(path) for path in cifs_paths)]
266+
267+
268+
_cifs_table = _generate_cifs_table()
269+
270+
271+
def on_cifs(fname):
272+
""" Checks whether a PATH is on a CIFS filesystem mounted in a POSIX
273+
host (i.e., has the "mount" command).
274+
275+
CIFS shares are how Docker mounts Windows host directories into containers.
276+
CIFS has partial support for symlinks that can break, causing misleading
277+
errors, so this test is used to disable them on such systems.
278+
"""
258279
# Only the first match counts
259-
for fspath, fstype in paths_types:
280+
for fspath, fstype in _cifs_table:
260281
if fname.startswith(fspath):
261282
return fstype == 'cifs'
262283
return False
@@ -314,7 +335,7 @@ def copyfile(originalfile, newfile, copy=False, create_new=False,
314335
hashmethod = config.get('execution', 'hash_method').lower()
315336

316337
# Don't try creating symlinks on CIFS
317-
if _on_cifs(newfile):
338+
if copy is False and on_cifs(newfile):
318339
copy = True
319340

320341
# Existing file

0 commit comments

Comments
 (0)