mirror of
https://github.com/containers/fuse-overlayfs.git
synced 2025-08-04 02:15:58 -04:00
main: attempt an inode free on releasedir
if the reference held by the directory is the last one, it would miss to clean up the inode. Fix it by calling do_forget. Closes: https://github.com/containers/fuse-overlayfs/issues/238 Signed-off-by: Giuseppe Scrivano <gscrivan@redhat.com>
This commit is contained in:
parent
e9cdbc444c
commit
6e2675593c
22
main.c
22
main.c
@ -948,18 +948,14 @@ drop_node_from_ino (Hash_table *inodes, struct ovl_node *node)
|
|||||||
{
|
{
|
||||||
struct ovl_ino *ino;
|
struct ovl_ino *ino;
|
||||||
struct ovl_node *it, *prev = NULL;
|
struct ovl_node *it, *prev = NULL;
|
||||||
size_t len = 0;
|
|
||||||
|
|
||||||
ino = node->ino;
|
ino = node->ino;
|
||||||
|
|
||||||
for (it = ino->node; it; it = it->next_link)
|
/* If it is the only node referenced by the inode, do not destroy it. */
|
||||||
len++;
|
if (ino->node == node && node->next_link == NULL)
|
||||||
|
|
||||||
if (len == 1 && node->ino->lookups > 0)
|
|
||||||
return;
|
return;
|
||||||
|
|
||||||
node->ino = NULL;
|
node->ino = NULL;
|
||||||
ino->lookups -= node->node_lookups;
|
|
||||||
|
|
||||||
for (it = ino->node; it; it = it->next_link)
|
for (it = ino->node; it; it = it->next_link)
|
||||||
{
|
{
|
||||||
@ -1161,17 +1157,17 @@ register_inode (struct ovl_data *lo, struct ovl_node *n, mode_t mode)
|
|||||||
return ino->node;
|
return ino->node;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static bool
|
||||||
do_forget (struct ovl_data *lo, fuse_ino_t ino, uint64_t nlookup)
|
do_forget (struct ovl_data *lo, fuse_ino_t ino, uint64_t nlookup)
|
||||||
{
|
{
|
||||||
struct ovl_ino *i;
|
struct ovl_ino *i;
|
||||||
|
|
||||||
if (ino == FUSE_ROOT_ID || ino == 0)
|
if (ino == FUSE_ROOT_ID || ino == 0)
|
||||||
return;
|
return false;
|
||||||
|
|
||||||
i = lookup_inode (lo, ino);
|
i = lookup_inode (lo, ino);
|
||||||
if (i == NULL)
|
if (i == NULL || i == &dummy_ino)
|
||||||
return;
|
return false;
|
||||||
|
|
||||||
i->lookups -= nlookup;
|
i->lookups -= nlookup;
|
||||||
if (i->lookups <= 0)
|
if (i->lookups <= 0)
|
||||||
@ -1179,6 +1175,7 @@ do_forget (struct ovl_data *lo, fuse_ino_t ino, uint64_t nlookup)
|
|||||||
hash_delete (lo->inodes, i);
|
hash_delete (lo->inodes, i);
|
||||||
inode_free (i);
|
inode_free (i);
|
||||||
}
|
}
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@ -2338,6 +2335,7 @@ ovl_releasedir (fuse_req_t req, fuse_ino_t ino, struct fuse_file_info *fi)
|
|||||||
cleanup_lock int l = enter_big_lock ();
|
cleanup_lock int l = enter_big_lock ();
|
||||||
size_t s;
|
size_t s;
|
||||||
struct ovl_dirp *d = ovl_dirp (fi);
|
struct ovl_dirp *d = ovl_dirp (fi);
|
||||||
|
struct ovl_data *lo = ovl_data (req);
|
||||||
|
|
||||||
if (UNLIKELY (ovl_debug (req)))
|
if (UNLIKELY (ovl_debug (req)))
|
||||||
fprintf (stderr, "ovl_releasedir(ino=%" PRIu64 ")\n", ino);
|
fprintf (stderr, "ovl_releasedir(ino=%" PRIu64 ")\n", ino);
|
||||||
@ -2345,9 +2343,7 @@ ovl_releasedir (fuse_req_t req, fuse_ino_t ino, struct fuse_file_info *fi)
|
|||||||
for (s = 2; s < d->tbl_size; s++)
|
for (s = 2; s < d->tbl_size; s++)
|
||||||
{
|
{
|
||||||
d->tbl[s]->node_lookups--;
|
d->tbl[s]->node_lookups--;
|
||||||
if (d->tbl[s]->ino)
|
if (! do_forget (lo, (fuse_ino_t) d->tbl[s]->ino, 1))
|
||||||
d->tbl[s]->ino->lookups--;
|
|
||||||
else
|
|
||||||
{
|
{
|
||||||
if (d->tbl[s]->node_lookups == 0)
|
if (d->tbl[s]->node_lookups == 0)
|
||||||
node_free (d->tbl[s]);
|
node_free (d->tbl[s]);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user