Skip to content

Instantly share code, notes, and snippets.

@pfactum
Created January 21, 2016 23:59
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save pfactum/9524fa2054cc48278ea8 to your computer and use it in GitHub Desktop.
Save pfactum/9524fa2054cc48278ea8 to your computer and use it in GitHub Desktop.
diff --git a/xlators/mount/fuse/src/fuse-bridge.c b/xlators/mount/fuse/src/fuse-bridge.c
index c748150..e9a5bef 100644
--- a/xlators/mount/fuse/src/fuse-bridge.c
+++ b/xlators/mount/fuse/src/fuse-bridge.c
@@ -3834,10 +3834,11 @@ fuse_setlk (xlator_t *this, fuse_in_header_t *finh, void *msg)
static void *
notify_kernel_loop (void *data)
{
+ uint32_t len = 0;
+ ssize_t rv = 0;
xlator_t *this = NULL;
fuse_private_t *priv = NULL;
- struct fuse_out_header *fouh = NULL;
- int rv = 0;
+ struct fuse_out_header *pfoh = NULL;
fuse_invalidate_node_t *node = NULL;
this = data;
@@ -3853,27 +3854,49 @@ notify_kernel_loop (void *data)
node = list_entry (priv->invalidate_list.next,
fuse_invalidate_node_t, next);
- if (node == NULL)
+ if (node == NULL) {
+ pthread_mutex_unlock (&priv->invalidate_mutex);
continue;
+ }
list_del_init (&node->next);
}
pthread_mutex_unlock (&priv->invalidate_mutex);
+ pfoh = (struct fuse_out_header *)node->inval_buf;
+ memcpy (&len, &pfoh->len, sizeof(len));
+ /*
+ * a simple
+ * len = pfoh->len;
+ * works on x86, but takes a multiple insn cycle hit
+ * when pfoh->len is not correctly aligned, possibly
+ * even stalling the insn pipeline.
+ * Other architectures will not be so forgiving. If
+ * we're lucky the memcpy will be inlined by the
+ * compiler, and might be as fast or faster without
+ * the risk of stalling the insn pipeline.
+ * And after so carefully getting it nicely aligned,
+ * let's use it on the call to sys_write as well, so
+ * we don't incur another multiple insn cycle hit.
+ */
- fouh = (struct fuse_out_header *)node->inval_buf;
-
- rv = write (priv->fd, node->inval_buf, fouh->len);
+ rv = write (priv->fd, node->inval_buf, len);
GF_FREE (node);
- if (rv != fouh->len && !(rv == -1 && errno == ENOENT))
+ if (rv != len && !(rv == -1 && errno == ENOENT)) {
+ gf_log ("glusterfs-fuse", GF_LOG_INFO,
+ "len: %u, rv: %zd, errno: %d", len, rv, errno);
break;
+ }
+
+ GF_FREE (node);
}
- gf_log ("glusterfs-fuse", GF_LOG_INFO,
+ gf_log ("glusterfs-fuse", GF_LOG_ERROR,
"kernel notifier loop terminated");
+ GF_FREE (node);
return NULL;
}
#endif
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment