File Do-not-exceed-cache-size-limit-under-pressure.patch of Package davfs2
From d171a9c68976e9fcf76d89777363acdb11bb06b3 Mon Sep 17 00:00:00 2001
From: Ali Abdallah <ali.abdallah@suse.com>
Date: Thu, 12 Mar 2026 14:23:06 +0100
Subject: [PATCH] Do not exceed cache size limit under pressure
Under pressure (rsync for example), a lot of nodes are marked as dirty
and their corresponding cache is never freed. We try with this patch to
not exceed cache size limit, even under pressure.
Fixes #31
---
src/cache.c | 25 ++++++++++++++++++++-----
src/mount_davfs.c | 2 ++
2 files changed, 22 insertions(+), 5 deletions(-)
diff --git a/src/cache.c b/src/cache.c
index ea7240a..aac3c7b 100644
--- a/src/cache.c
+++ b/src/cache.c
@@ -2920,12 +2920,16 @@ parse_index(void)
static void
resize_cache(void)
{
+ int free_more_cache = 0;
+ int last = 0;
+
if (debug)
syslog(LOG_MAKEPRI(LOG_DAEMON, LOG_DEBUG),
"resize cache: %llu of %llu MiBytes used.",
(cache_size + 0x80000) / 0x100000,
(max_cache_size + 0x80000) / 0x100000);
+try_once_more:
while (1) {
dav_node *least_recent = NULL;
cache_size = 0;
@@ -2934,8 +2938,9 @@ resize_cache(void)
dav_node *node = table[i];
while (node) {
if (is_cached(node)) {
- if (!is_open(node) && !is_dirty(node)
- && !is_created(node) && !is_backup(node)
+ if (!is_open(node)
+ && (free_more_cache || !is_dirty(node))
+ && (free_more_cache || !is_backup(node))
&& (!least_recent
|| node->atime < least_recent->atime))
least_recent = node;
@@ -2947,15 +2952,25 @@ resize_cache(void)
if (cache_size < max_cache_size)
break;
if (!least_recent) {
- syslog(LOG_MAKEPRI(LOG_DAEMON, LOG_ERR),
- _("open files exceed max cache size by %llu MiBytes"),
- (cache_size - max_cache_size + 0x80000) / 0x100000);
+ unsigned long long oversize;
+ free_more_cache = 1;
+
+ oversize = (cache_size - max_cache_size + 0x80000) / 0x100000;
+ if (oversize)
+ syslog(LOG_MAKEPRI(LOG_DAEMON, LOG_ERR),
+ _("open files exceed max cache size by %llu MiBytes"),
+ (cache_size - max_cache_size + 0x80000) / 0x100000);
break;
}
delete_cache_file(least_recent);
cache_size -= least_recent->size;
}
+ if (free_more_cache && !last) {
+ last = 1;
+ goto try_once_more;
+ }
+
if (debug)
syslog(LOG_MAKEPRI(LOG_DAEMON, LOG_DEBUG),
" %llu of %llu MiBytes used.",
diff --git a/src/mount_davfs.c b/src/mount_davfs.c
index ced5385..13748b0 100644
--- a/src/mount_davfs.c
+++ b/src/mount_davfs.c
@@ -275,6 +275,8 @@ main(int argc, char *argv[])
dav_init_cache(args, mpoint);
+ dav_tidy_cache();
+
int dev = 0;
if (args->buf_size && args->buf_size < 64) {
WARN("WARNING: Buffer size is too small, increasing to 64");
--
2.51.0