From 0db6ecbbd95525ce38b29bc58a98932a5c987dab Mon Sep 17 00:00:00 2001 From: Giuseppe Scrivano Date: Fri, 16 Apr 2021 21:53:28 +0200 Subject: [PATCH] main: move directory load at readdir time move the logic for loading the directory content at readdir time when the offset is set to 0, so that any new file to the directory is propagated. Closes: https://github.com/containers/fuse-overlayfs/issues/287 Signed-off-by: Giuseppe Scrivano --- main.c | 70 ++++++++++++++++++++++++++++++++++++++-------------------- 1 file changed, 46 insertions(+), 24 deletions(-) diff --git a/main.c b/main.c index 4be2c9e..284863a 100644 --- a/main.c +++ b/main.c @@ -2152,13 +2152,47 @@ ovl_dirp (struct fuse_file_info *fi) return (struct ovl_dirp *) (uintptr_t) fi->fh; } +static int +reload_tbl (struct ovl_data *lo, struct ovl_dirp *d, struct ovl_node *node) +{ + size_t counter = 0; + struct ovl_node *it; + + node = reload_dir (lo, node); + if (node == NULL) + return -1; + + if (d->tbl) + free (d->tbl); + + d->offset = 0; + d->parent = node; + d->tbl_size = hash_get_n_entries (node->children) + 2; + d->tbl = calloc (sizeof (struct ovl_node *), d->tbl_size); + if (d->tbl == NULL) + { + errno = ENOMEM; + return -1; + } + + d->tbl[counter++] = node; + d->tbl[counter++] = node->parent; + + for (it = hash_get_first (node->children); it; it = hash_get_next (node->children, it)) + { + it->ino->lookups++; + it->node_lookups++; + d->tbl[counter++] = it; + } + + return 0; +} + static void ovl_opendir (fuse_req_t req, fuse_ino_t ino, struct fuse_file_info *fi) { - size_t counter = 0; struct ovl_node *node; struct ovl_data *lo = ovl_data (req); - struct ovl_node *it; struct ovl_dirp *d = calloc (1, sizeof (struct ovl_dirp)); cleanup_lock int l = enter_big_lock (); @@ -2184,29 +2218,7 @@ ovl_opendir (fuse_req_t req, fuse_ino_t ino, struct fuse_file_info *fi) goto out_errno; } - node = reload_dir (lo, node); - if (node == NULL) - goto out_errno; - - d->offset = 0; d->parent = node; - d->tbl_size = hash_get_n_entries (node->children) + 2; - d->tbl = malloc (sizeof (struct ovl_node *) * d->tbl_size); - if (d->tbl == NULL) - { - errno = ENOMEM; - goto out_errno; - } - - d->tbl[counter++] = node; - d->tbl[counter++] = node->parent; - - for (it = hash_get_first (node->children); it; it = hash_get_next (node->children, it)) - { - it->ino->lookups++; - it->node_lookups++; - d->tbl[counter++] = it; - } fi->fh = (uintptr_t) d; if (get_timeout (lo) > 0) @@ -2326,6 +2338,16 @@ ovl_do_readdir (fuse_req_t req, fuse_ino_t ino, size_t size, fuse_reply_err (req, errno); return; } + + if (offset == 0 || d->tbl == NULL) + { + if (reload_tbl (lo, d, d->parent) < 0) + { + fuse_reply_err (req, errno); + return; + } + } + p = buffer; for (; remaining > 0 && offset < d->tbl_size; offset++) {