diff options
author | Tavian Barnes <tavianator@tavianator.com> | 2023-07-17 19:05:23 -0400 |
---|---|---|
committer | Tavian Barnes <tavianator@tavianator.com> | 2023-07-17 20:03:33 -0400 |
commit | 196c36bb13de94c977a3e360dc5fa529efe2c5ca (patch) | |
tree | a7093dda8a03535e362e586e27e340e313ad43d2 /src/bftw.c | |
parent | 3cc581c0295465fd5dc2fc818aa92f48dd87788e (diff) | |
download | bfs-196c36bb13de94c977a3e360dc5fa529efe2c5ca.tar.xz |
bftw: Reserve space in the cache before opening files
This fixes a storm of EMFILE retries observed with -j1 on a very large
directory tree.
Fixes: 7888fbababd22190e9f919fc272957426a27969e
Diffstat (limited to 'src/bftw.c')
-rw-r--r-- | src/bftw.c | 18 |
1 files changed, 15 insertions, 3 deletions
@@ -572,7 +572,13 @@ static int bftw_cache_reserve(struct bftw_state *state) { } } - return bftw_cache_pop(cache); + if (bftw_cache_pop(cache) != 0) { + errno = EMFILE; + return -1; + } + + bfs_assert(cache->capacity > 0); + return 0; } /** Open a bftw_file relative to another one. */ @@ -587,8 +593,13 @@ static int bftw_file_openat(struct bftw_state *state, struct bftw_file *file, st at_fd = base->fd; } + int fd = -1; + if (bftw_cache_reserve(state) != 0) { + goto unpin; + } + int flags = O_RDONLY | O_CLOEXEC | O_DIRECTORY; - int fd = openat(at_fd, at_path, flags); + fd = openat(at_fd, at_path, flags); if (fd < 0 && errno == EMFILE) { if (bftw_cache_pop(cache) == 0) { @@ -597,6 +608,7 @@ static int bftw_file_openat(struct bftw_state *state, struct bftw_file *file, st cache->capacity = 1; } +unpin: if (base) { bftw_cache_unpin(cache, base); } @@ -606,7 +618,7 @@ static int bftw_file_openat(struct bftw_state *state, struct bftw_file *file, st bftw_cache_add(cache, file); } - return file->fd; + return fd; } /** Open a bftw_file. */ |