From 0f72a8a0cf5d2a4950f119f2434f73169f112e31 Mon Sep 17 00:00:00 2001 From: Thomas Waldmann Date: Mon, 11 Mar 2019 02:27:41 +0100 Subject: [PATCH] lrucache: regularly remove old FDs, fixes #4427 --- src/borg/lrucache.py | 1 - src/borg/repository.py | 25 ++++++++++++++++--------- 2 files changed, 16 insertions(+), 10 deletions(-) diff --git a/src/borg/lrucache.py b/src/borg/lrucache.py index d362bc92b..4f7f1f829 100644 --- a/src/borg/lrucache.py +++ b/src/borg/lrucache.py @@ -50,7 +50,6 @@ class LRUCache: self._dispose(value) self._cache.clear() - # useful for testing def items(self): return self._cache.items() diff --git a/src/borg/repository.py b/src/borg/repository.py index 3137d0809..ef70ccd69 100644 --- a/src/borg/repository.py +++ b/src/borg/repository.py @@ -1171,6 +1171,7 @@ class LoggedIO: self.segments_per_dir = segments_per_dir self.offset = 0 self._write_fd = None + self._fds_cleaned = 0 def close(self): self.close_segment() @@ -1301,20 +1302,26 @@ class LoggedIO: self.fds[segment] = (now, fd) return fd + def clean_old(): + # we regularly get rid of all old FDs here: + if now - self._fds_cleaned > FD_MAX_AGE // 8: + self._fds_cleaned = now + for k, ts_fd in list(self.fds.items()): + ts, fd = ts_fd + if now - ts > FD_MAX_AGE: + # we do not want to touch long-unused file handles to + # avoid ESTALE issues (e.g. on network filesystems). + del self.fds[k] + + clean_old() try: ts, fd = self.fds[segment] except KeyError: fd = open_fd() else: - if now - ts > FD_MAX_AGE: - # we do not want to touch long-unused file handles to - # avoid ESTALE issues (e.g. on network filesystems). - del self.fds[segment] - fd = open_fd() - else: - # fd is fresh enough, so we use it. - # also, we update the timestamp of the lru cache entry. - self.fds.upd(segment, (now, fd)) + # we only have fresh enough stuff here. + # update the timestamp of the lru cache entry. + self.fds.upd(segment, (now, fd)) return fd def close_segment(self):