diff options
author | Xavier Hernandez <xhernandez@datalab.es> | 2016-01-30 22:35:19 +0100 |
---|---|---|
committer | Kaleb KEITHLEY <kkeithle@redhat.com> | 2016-02-03 23:55:34 -0800 |
commit | bacdf9335bc674d87ca408feafa3515fb00f47b2 (patch) | |
tree | 4eed5977a271df5df28cb8195e88127db4e9fe2a /xlators/mount/fuse/src/fuse-bridge.c | |
parent | 61c2aec3034714e513bcc3ad9ea61c2bb63b07fe (diff) |
fuse: fix inode and dentry leaks
When a readdirp was executed, the nlookup count for each inode of the
returned entries was incremented. However the kernel does not increment
the counter for '.' and '..' entries.
This caused that kernel sent forgets with a counter smaller than the
inode's current value. This prevented these inodes to be retired when
ref count was 0.
Change-Id: I36f3736c86d1cc20adabbbc133ce4edeff62db78
Signed-off-by: Xavier Hernandez <xhernandez@datalab.es>
Reviewed-on: http://review.gluster.org/13324
Smoke: Gluster Build System <jenkins@build.gluster.com>
Reviewed-by: Raghavendra Bhat <raghavendra@redhat.com>
Tested-by: Kaleb KEITHLEY <kkeithle@redhat.com>
CentOS-regression: Gluster Build System <jenkins@build.gluster.com>
NetBSD-regression: NetBSD Build System <jenkins@build.gluster.org>
Reviewed-by: Kaleb KEITHLEY <kkeithle@redhat.com>
Diffstat (limited to 'xlators/mount/fuse/src/fuse-bridge.c')
-rw-r--r-- | xlators/mount/fuse/src/fuse-bridge.c | 51 |
1 files changed, 29 insertions, 22 deletions
diff --git a/xlators/mount/fuse/src/fuse-bridge.c b/xlators/mount/fuse/src/fuse-bridge.c index bd7d5adf9db..87db40fd8c9 100644 --- a/xlators/mount/fuse/src/fuse-bridge.c +++ b/xlators/mount/fuse/src/fuse-bridge.c @@ -223,11 +223,16 @@ fuse_invalidate_entry (xlator_t *this, uint64_t fuse_ino) if (!priv->reverse_fuse_thread_started) return; + inode = fuse_ino_to_inode(fuse_ino, this); + if (inode == NULL) { + return; + } + list_for_each_entry (dentry, &inode->dentry_list, inode_list) { node = GF_CALLOC (1, sizeof (*node), gf_fuse_mt_invalidate_node_t); if (node == NULL) - return; + break; INIT_LIST_HEAD (&node->next); @@ -237,8 +242,6 @@ fuse_invalidate_entry (xlator_t *this, uint64_t fuse_ino) fouh->unique = 0; fouh->error = FUSE_NOTIFY_INVAL_ENTRY; - inode = fuse_ino_to_inode (fuse_ino, this); - nlen = strlen (dentry->name); fouh->len = sizeof (*fouh) + sizeof (*fnieo) + nlen + 1; fnieo->parent = inode_to_fuse_nodeid (dentry->parent); @@ -428,9 +431,6 @@ fuse_entry_cbk (call_frame_t *frame, void *cookie, xlator_t *this, linked_inode = inode_link (inode, state->loc.parent, state->loc.name, buf); - if (linked_inode != inode) { - } - inode_lookup (linked_inode); feo.nodeid = inode_to_fuse_nodeid (linked_inode); @@ -2804,12 +2804,14 @@ fuse_readdirp_cbk (call_frame_t *frame, void *cookie, xlator_t *this, if (!linked_inode) goto next_entry; - inode_lookup (linked_inode); + if ((strcmp(entry->d_name, ".") != 0) && + (strcmp(entry->d_name, "..") != 0)) { + inode_lookup (linked_inode); + inode_set_need_lookup (linked_inode, this); + } feo->nodeid = inode_to_fuse_nodeid (linked_inode); - inode_set_need_lookup (linked_inode, this); - inode_unref (linked_inode); feo->entry_valid = @@ -4132,7 +4134,7 @@ fuse_first_lookup (xlator_t *this) dict_t *dict = NULL; struct fuse_first_lookup stub; uuid_t gfid; - int ret; + int ret = -1; priv = this->private; @@ -4146,7 +4148,7 @@ fuse_first_lookup (xlator_t *this) frame = create_frame (this, this->ctx->pool); if (!frame) { gf_log ("fuse", GF_LOG_ERROR, "failed to create frame"); - return -1; + goto out; } frame->root->type = GF_OP_TYPE_FOP; @@ -4162,20 +4164,22 @@ fuse_first_lookup (xlator_t *this) memset (gfid, 0, 16); gfid[15] = 1; ret = dict_set_static_bin (dict, "gfid-req", gfid, 16); - if (ret) + if (ret) { gf_log (xl->name, GF_LOG_ERROR, "failed to set 'gfid-req'"); + } else { + STACK_WIND (frame, fuse_first_lookup_cbk, xl, xl->fops->lookup, + &loc, dict); - STACK_WIND (frame, fuse_first_lookup_cbk, xl, xl->fops->lookup, - &loc, dict); - dict_unref (dict); - - pthread_mutex_lock (&stub.mutex); - { - while (!stub.fin) { - pthread_cond_wait (&stub.cond, &stub.mutex); + pthread_mutex_lock (&stub.mutex); + { + while (!stub.fin) { + pthread_cond_wait (&stub.cond, &stub.mutex); + } } + pthread_mutex_unlock (&stub.mutex); } - pthread_mutex_unlock (&stub.mutex); + + dict_unref (dict); pthread_mutex_destroy (&stub.mutex); pthread_cond_destroy (&stub.cond); @@ -4183,7 +4187,10 @@ fuse_first_lookup (xlator_t *this) frame->local = NULL; STACK_DESTROY (frame->root); - return 0; +out: + inode_unref(loc.inode); + + return ret; } |