From 291083dd1ba289cf24bbb40d5ae1d980fbe609c7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Paulo=20Jer=C3=B4nimo?= Date: Tue, 7 Jul 2026 10:57:54 -0300 Subject: [PATCH] cache: reopen remote directory handle on cache-miss readdir cache_readdir() reused the already-open remote directory handle whenever the cached listing was missing or invalidated, instead of just when it was still valid. The SFTP directory stream is positional: once read to EOF, rereading the same handle after a local create/delete/rename returns EOF again, making the directory look empty even though its contents changed on the server. Close and reopen the handle before the live read whenever we fall through the cache-hit fast path, so the read reflects the current directory instead of a stale, exhausted stream. --- cache.c | 22 +++++++++++++++++++--- 1 file changed, 19 insertions(+), 3 deletions(-) diff --git a/cache.c b/cache.c index 4277163e..4d87c348 100644 --- a/cache.c +++ b/cache.c @@ -403,9 +403,25 @@ static int cache_readdir(const char *path, void *buf, fuse_fill_dir_t filler, pthread_mutex_unlock(&cache.lock); cfi = (struct file_handle*) fi->fh; - if(cfi->is_open) - fi->fh = cfi->fs_fh; - else { + if (cfi->is_open) { + /* + * We only reach here when the cached listing was missing or + * had been invalidated (e.g. by a create/delete/rename + * through this mount) - the fast path above already returned + * for a valid cache hit. The remote directory stream behind + * fs_fh is positional: if it was already read to EOF by an + * earlier call, reusing it here just returns EOF again, + * making the directory appear empty even though its contents + * changed. Close it and open a fresh handle so the read + * below actually reflects the current directory. + */ + if (cache.next_oper->releasedir) { + fi->fh = cfi->fs_fh; + cache.next_oper->releasedir(path, fi); + } + cfi->is_open = 0; + } + if (!cfi->is_open) { if(cache.next_oper->opendir) { err = cache.next_oper->opendir(path, fi); if(err)