summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--xlators/mount/fuse/src/fuse-bridge.c124
-rw-r--r--xlators/mount/fuse/src/fuse-bridge.h22
-rw-r--r--xlators/mount/fuse/src/fuse-mem-types.h1
3 files changed, 84 insertions, 63 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);
diff --git a/xlators/mount/fuse/src/fuse-bridge.h b/xlators/mount/fuse/src/fuse-bridge.h
index ea346c05f9e..08af454be63 100644
--- a/xlators/mount/fuse/src/fuse-bridge.h
+++ b/xlators/mount/fuse/src/fuse-bridge.h
@@ -110,8 +110,9 @@ struct fuse_private {
char *fuse_mountopts;
/* For fuse-reverse-validation */
- int revchan_in;
- int revchan_out;
+ struct list_head invalidate_list;
+ pthread_cond_t invalidate_cond;
+ pthread_mutex_t invalidate_mutex;
gf_boolean_t reverse_fuse_thread_started;
/* For communicating with separate mount thread. */
@@ -133,6 +134,18 @@ struct fuse_private {
};
typedef struct fuse_private fuse_private_t;
+#define INVAL_BUF_SIZE (sizeof (struct fuse_out_header) + \
+ max (sizeof (struct fuse_notify_inval_inode_out), \
+ sizeof (struct fuse_notify_inval_entry_out) + \
+ NAME_MAX + 1))
+
+
+struct fuse_invalidate_node {
+ char inval_buf[INVAL_BUF_SIZE];
+ struct list_head next;
+};
+typedef struct fuse_invalidate_node fuse_invalidate_node_t;
+
struct fuse_graph_switch_args {
xlator_t *this;
xlator_t *old_subvol;
@@ -140,11 +153,6 @@ struct fuse_graph_switch_args {
};
typedef struct fuse_graph_switch_args fuse_graph_switch_args_t;
-#define INVAL_BUF_SIZE (sizeof (struct fuse_out_header) + \
- max (sizeof (struct fuse_notify_inval_inode_out), \
- sizeof (struct fuse_notify_inval_entry_out) + \
- NAME_MAX + 1))
-
#define FUSE_EVENT_HISTORY_SIZE 1024
#define _FH_TO_FD(fh) ((fd_t *)(uintptr_t)(fh))
diff --git a/xlators/mount/fuse/src/fuse-mem-types.h b/xlators/mount/fuse/src/fuse-mem-types.h
index 28b4dfbdd04..2b4b473813d 100644
--- a/xlators/mount/fuse/src/fuse-mem-types.h
+++ b/xlators/mount/fuse/src/fuse-mem-types.h
@@ -22,6 +22,7 @@ enum gf_fuse_mem_types_ {
gf_fuse_mt_fd_ctx_t,
gf_fuse_mt_graph_switch_args_t,
gf_fuse_mt_gids_t,
+ gf_fuse_mt_invalidate_node_t,
gf_fuse_mt_end
};
#endif