diff options
author | TW <tw@waldmann-edv.de> | 2017-10-28 13:31:47 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2017-10-28 13:31:47 +0200 |
commit | 926b1c6374ae51f1aec0060a616666068aab94f4 (patch) | |
tree | ae2584a4279f4ea8993d520ab7ab22121a1b9508 | |
parent | c0b905875953a3819cb8b1454d3985608dff1934 (diff) | |
parent | 36f2a4e1dcac69f58e5cfc8141a65b5006f32cf3 (diff) |
Merge pull request #3212 from ThomasWaldmann/stat-after-match
don't do stat() when not recursing into excluded dir, fixes #3209
-rw-r--r-- | src/borg/archiver.py | 37 |
1 files changed, 23 insertions, 14 deletions
diff --git a/src/borg/archiver.py b/src/borg/archiver.py index 32983ade8..b09490bf2 100644 --- a/src/borg/archiver.py +++ b/src/borg/archiver.py @@ -537,20 +537,27 @@ class Archiver: This should only raise on critical errors. Per-item errors must be handled within this method. """ - if st is None: - with backup_io('stat'): - st = os.stat(path, follow_symlinks=False) - - recurse_excluded_dir = False - if not matcher.match(path): - self.print_file_status('x', path) - - if stat.S_ISDIR(st.st_mode) and matcher.recurse_dir: - recurse_excluded_dir = True + try: + recurse_excluded_dir = False + if matcher.match(path): + if st is None: + with backup_io('stat'): + st = os.stat(path, follow_symlinks=False) else: - return + self.print_file_status('x', path) + # get out here as quickly as possible: + # we only need to continue if we shall recurse into an excluded directory. + # if we shall not recurse, then do not even touch (stat()) the item, it + # could trigger an error, e.g. if access is forbidden, see #3209. + if not matcher.recurse_dir: + return + if st is None: + with backup_io('stat'): + st = os.stat(path, follow_symlinks=False) + recurse_excluded_dir = stat.S_ISDIR(st.st_mode) + if not recurse_excluded_dir: + return - try: if (st.st_ino, st.st_dev) in skip_inodes: return # if restrict_dev is given, we do not want to recurse into a new filesystem, @@ -1823,10 +1830,12 @@ class Archiver: may specify the backup roots (starting points) and patterns for inclusion/exclusion. A root path starts with the prefix `R`, followed by a path (a plain path, not a file pattern). An include rule starts with the prefix +, an exclude rule starts - with the prefix -, both followed by a pattern. + with the prefix -, an exclude-norecurse rule starts with !, all followed by a pattern. Inclusion patterns are useful to include paths that are contained in an excluded path. The first matching pattern is used so if an include pattern matches before - an exclude pattern, the file is backed up. + an exclude pattern, the file is backed up. If an exclude-norecurse pattern matches + a directory, it won't recurse into it and won't discover any potential matches for + include rules below that directory. Note that the default pattern style for ``--pattern`` and ``--patterns-from`` is shell style (`sh:`), so those patterns behave similar to rsync include/exclude |