summaryrefslogtreecommitdiffstats
path: root/xlators/mount/fuse/src/fuse-bridge.c
diff options
context:
space:
mode:
Diffstat (limited to 'xlators/mount/fuse/src/fuse-bridge.c')
-rw-r--r--xlators/mount/fuse/src/fuse-bridge.c124
1 files changed, 68 insertions, 56 deletions
diff --git a/xlators/mount/fuse/src/fuse-bridge.c b/xlators/mount/fuse/src/fuse-bridge.c
index bf63697233b..81c247a1953 100644
--- a/xlators/mount/fuse/src/fuse-bridge.c
+++ b/xlators/mount/fuse/src/fuse-bridge.c
@@ -216,37 +216,43 @@ fuse_invalidate_entry (xlator_t *this, uint64_t fuse_ino)
dentry_t *dentry = NULL;
inode_t *inode = NULL;
size_t nlen = 0;
- int rv = 0;
- char inval_buf[INVAL_BUF_SIZE] = {0,};
-
- fouh = (struct fuse_out_header *)inval_buf;
- fnieo = (struct fuse_notify_inval_entry_out *)(fouh + 1);
+ fuse_invalidate_node_t *node = NULL;
priv = this->private;
- if (priv->revchan_out == -1)
+
+ if (!priv->reverse_fuse_thread_started)
return;
- fouh->unique = 0;
- fouh->error = FUSE_NOTIFY_INVAL_ENTRY;
+ 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;
- inode = fuse_ino_to_inode (fuse_ino, this);
+ INIT_LIST_HEAD (&node->next);
+
+ fouh = (struct fuse_out_header *)node->inval_buf;
+ fnieo = (struct fuse_notify_inval_entry_out *)(fouh + 1);
+
+ fouh->unique = 0;
+ fouh->error = FUSE_NOTIFY_INVAL_ENTRY;
+
+ inode = fuse_ino_to_inode (fuse_ino, this);
- list_for_each_entry (dentry, &inode->dentry_list, inode_list) {
nlen = strlen (dentry->name);
fouh->len = sizeof (*fouh) + sizeof (*fnieo) + nlen + 1;
fnieo->parent = inode_to_fuse_nodeid (dentry->parent);
fnieo->namelen = nlen;
- strcpy (inval_buf + sizeof (*fouh) + sizeof (*fnieo), dentry->name);
-
- rv = write (priv->revchan_out, inval_buf, fouh->len);
- if (rv != fouh->len) {
- gf_log ("glusterfs-fuse", GF_LOG_ERROR,
- "kernel notification daemon defunct");
+ strcpy (node->inval_buf + sizeof (*fouh) + sizeof (*fnieo),
+ dentry->name);
- close (priv->fd);
- break;
+ pthread_mutex_lock (&priv->invalidate_mutex);
+ {
+ list_add_tail (&node->next, &priv->invalidate_list);
+ pthread_cond_signal (&priv->invalidate_cond);
}
+ pthread_mutex_unlock (&priv->invalidate_mutex);
gf_log ("glusterfs-fuse", GF_LOG_TRACE, "INVALIDATE entry: "
"%"PRIu64"/%s", fnieo->parent, dentry->name);
@@ -277,18 +283,23 @@ fuse_invalidate_inode(xlator_t *this, uint64_t fuse_ino)
struct fuse_out_header *fouh = NULL;
struct fuse_notify_inval_inode_out *fniio = NULL;
fuse_private_t *priv = NULL;
- int rv = 0;
- char inval_buf[INVAL_BUF_SIZE] = {0};
+ fuse_invalidate_node_t *node = NULL;
inode_t *inode = NULL;
- fouh = (struct fuse_out_header *) inval_buf;
- fniio = (struct fuse_notify_inval_inode_out *) (fouh + 1);
-
priv = this->private;
- if (priv->revchan_out < 0)
+ if (!priv->reverse_fuse_thread_started)
return;
+ node = GF_CALLOC (1, sizeof (*node), gf_fuse_mt_invalidate_node_t);
+ if (node == NULL)
+ return;
+
+ INIT_LIST_HEAD (&node->next);
+
+ fouh = (struct fuse_out_header *) node->inval_buf;
+ fniio = (struct fuse_notify_inval_inode_out *) (fouh + 1);
+
fouh->unique = 0;
fouh->error = FUSE_NOTIFY_INVAL_INODE;
fouh->len = sizeof(struct fuse_out_header) +
@@ -301,12 +312,12 @@ fuse_invalidate_inode(xlator_t *this, uint64_t fuse_ino)
inode = fuse_ino_to_inode (fuse_ino, this);
- rv = write(priv->revchan_out, inval_buf, fouh->len);
- if (rv != fouh->len) {
- gf_log("glusterfs-fuse", GF_LOG_ERROR, "kernel notification "
- "daemon defunct");
- close(priv->fd);
+ pthread_mutex_lock (&priv->invalidate_mutex);
+ {
+ list_add_tail (&node->next, &priv->invalidate_list);
+ pthread_cond_signal (&priv->invalidate_cond);
}
+ pthread_mutex_unlock (&priv->invalidate_mutex);
gf_log ("glusterfs-fuse", GF_LOG_TRACE, "INVALIDATE inode: %" PRIu64,
fuse_ino);
@@ -3827,29 +3838,39 @@ notify_kernel_loop (void *data)
fuse_private_t *priv = NULL;
struct fuse_out_header *fouh = NULL;
int rv = 0;
-
- char inval_buf[INVAL_BUF_SIZE] = {0,};
+ fuse_invalidate_node_t *node = NULL;
this = data;
priv = this->private;
for (;;) {
- rv = read (priv->revchan_in, inval_buf, sizeof (*fouh));
- if (rv != sizeof (*fouh))
- break;
- fouh = (struct fuse_out_header *)inval_buf;
- rv = read (priv->revchan_in, inval_buf + sizeof (*fouh),
- fouh->len - sizeof (*fouh));
- if (rv != fouh->len - sizeof (*fouh))
- break;
- rv = write (priv->fd, inval_buf, fouh->len);
+ pthread_mutex_lock (&priv->invalidate_mutex);
+ {
+ while (list_empty (&priv->invalidate_list))
+ pthread_cond_wait (&priv->invalidate_cond,
+ &priv->invalidate_mutex);
+
+ node = list_entry (priv->invalidate_list.next,
+ fuse_invalidate_node_t, next);
+
+ if (node == NULL)
+ continue;
+
+ list_del_init (&node->next);
+ }
+ pthread_mutex_unlock (&priv->invalidate_mutex);
+
+
+ fouh = (struct fuse_out_header *)node->inval_buf;
+
+ rv = write (priv->fd, node->inval_buf, fouh->len);
+
+ GF_FREE (node);
+
if (rv != fouh->len && !(rv == -1 && errno == ENOENT))
break;
}
- close (priv->revchan_in);
- close (priv->revchan_out);
-
gf_log ("glusterfs-fuse", GF_LOG_INFO,
"kernel notifier loop terminated");
@@ -3865,7 +3886,6 @@ fuse_init (xlator_t *this, fuse_in_header_t *finh, void *msg)
fuse_private_t *priv = NULL;
int ret = 0;
#if FUSE_KERNEL_MINOR_VERSION >= 9
- int pfd[2] = {0,};
pthread_t messenger;
#endif
@@ -3918,16 +3938,6 @@ fuse_init (xlator_t *this, fuse_in_header_t *finh, void *msg)
/* Used for 'reverse invalidation of inode' */
if (fini->minor >= 12) {
- if (pipe(pfd) == -1) {
- gf_log ("glusterfs-fuse", GF_LOG_ERROR,
- "cannot create pipe pair (%s)",
- strerror(errno));
-
- close (priv->fd);
- goto out;
- }
- priv->revchan_in = pfd[0];
- priv->revchan_out = pfd[1];
ret = gf_thread_create (&messenger, NULL, notify_kernel_loop,
this);
if (ret != 0) {
@@ -5375,8 +5385,10 @@ init (xlator_t *this_xl)
this_xl->private = (void *) priv;
priv->mount_point = NULL;
priv->fd = -1;
- priv->revchan_in = -1;
- priv->revchan_out = -1;
+
+ INIT_LIST_HEAD (&priv->invalidate_list);
+ pthread_cond_init (&priv->invalidate_cond, NULL);
+ pthread_mutex_init (&priv->invalidate_mutex, NULL);
/* get options from option dictionary */
ret = dict_get_str (options, ZR_MOUNTPOINT_OPT, &value_string);