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 <gscrivan@redhat.com>
This commit is contained in:
Giuseppe Scrivano 2021-04-16 21:53:28 +02:00
parent af5cb1c04c
commit 0db6ecbbd9
No known key found for this signature in database
GPG Key ID: E4730F97F60286ED

70
main.c
View File

@ -2152,13 +2152,47 @@ ovl_dirp (struct fuse_file_info *fi)
return (struct ovl_dirp *) (uintptr_t) fi->fh; 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 static void
ovl_opendir (fuse_req_t req, fuse_ino_t ino, struct fuse_file_info *fi) 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_node *node;
struct ovl_data *lo = ovl_data (req); struct ovl_data *lo = ovl_data (req);
struct ovl_node *it;
struct ovl_dirp *d = calloc (1, sizeof (struct ovl_dirp)); struct ovl_dirp *d = calloc (1, sizeof (struct ovl_dirp));
cleanup_lock int l = enter_big_lock (); 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; goto out_errno;
} }
node = reload_dir (lo, node);
if (node == NULL)
goto out_errno;
d->offset = 0;
d->parent = node; 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; fi->fh = (uintptr_t) d;
if (get_timeout (lo) > 0) 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); fuse_reply_err (req, errno);
return; return;
} }
if (offset == 0 || d->tbl == NULL)
{
if (reload_tbl (lo, d, d->parent) < 0)
{
fuse_reply_err (req, errno);
return;
}
}
p = buffer; p = buffer;
for (; remaining > 0 && offset < d->tbl_size; offset++) for (; remaining > 0 && offset < d->tbl_size; offset++)
{ {