-
-
Save pfactum/9524fa2054cc48278ea8 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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