summaryrefslogtreecommitdiffstats
path: root/xlators/mount
diff options
context:
space:
mode:
authorXavier Hernandez <xhernandez@datalab.es>2016-01-30 22:35:19 +0100
committerKaleb KEITHLEY <kkeithle@redhat.com>2016-02-03 23:55:34 -0800
commitbacdf9335bc674d87ca408feafa3515fb00f47b2 (patch)
tree4eed5977a271df5df28cb8195e88127db4e9fe2a /xlators/mount
parent61c2aec3034714e513bcc3ad9ea61c2bb63b07fe (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')
-rw-r--r--xlators/mount/fuse/src/fuse-bridge.c51
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;
}