summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorCsaba Henk <csaba@redhat.com>2018-01-16 00:37:45 +0100
committerAmar Tumballi <amarts@redhat.com>2018-01-17 00:00:40 +0000
commit1b2a3a417f62a7b2aa15918d7be449c243d96b94 (patch)
treee9fbe190d598910b8516ce8723765edbc2272624
parent9404b0de3fd8ab5adc3a531d4cb37b56e1e3908f (diff)
fuse: write out reverse notification to fuse dump
BUG: 1534602 Change-Id: Ide42cf9cffe462d0cc46272b327c2a05999f09ba Signed-off-by: Csaba Henk <csaba@redhat.com>
-rw-r--r--xlators/mount/fuse/src/fuse-bridge.c89
1 files changed, 59 insertions, 30 deletions
diff --git a/xlators/mount/fuse/src/fuse-bridge.c b/xlators/mount/fuse/src/fuse-bridge.c
index ddf6d59eb3e..2ffaaf2528b 100644
--- a/xlators/mount/fuse/src/fuse-bridge.c
+++ b/xlators/mount/fuse/src/fuse-bridge.c
@@ -195,6 +195,59 @@ fusedump_setup_meta (struct iovec *iovs, char *dir,
iovs[3] = (struct iovec){ fsig, fsig->len };
}
+static int
+check_and_dump_fuse_W (fuse_private_t *priv, struct iovec *iov_out, int count,
+ ssize_t res)
+{
+ char w = 'W';
+ struct iovec diov[4] = {{0,},};
+ uint32_t fusedump_item_count = 3;
+ struct fusedump_timespec fts = {0,};
+ struct fusedump_signature fsig = {0,};
+ struct fuse_out_header *fouh = NULL;
+
+ if (res == -1) {
+ gf_log ("glusterfs-fuse", GF_LOG_ERROR,
+ "writing to fuse device failed: %s",
+ strerror (errno));
+ return errno;
+ }
+
+ fouh = iov_out[0].iov_base;
+ if (res != fouh->len) {
+ gf_log ("glusterfs-fuse", GF_LOG_ERROR,
+ "inconsistent write to fuse device: "
+ "written %zd, expectd %d",
+ res, fouh->len);
+ return EINVAL;
+ }
+
+ if (priv->fuse_dump_fd == -1)
+ return 0;
+
+ fusedump_setup_meta (diov, &w, &fusedump_item_count,
+ &fts, &fsig);
+
+ pthread_mutex_lock (&priv->fuse_dump_mutex);
+ res = sys_writev (priv->fuse_dump_fd, diov,
+ sizeof (diov)/sizeof (diov[0]));
+ if (res != -1)
+ res = sys_writev (priv->fuse_dump_fd, iov_out, count);
+ pthread_mutex_unlock (&priv->fuse_dump_mutex);
+
+ if (res == -1)
+ gf_log ("glusterfs-fuse", GF_LOG_ERROR,
+ "failed to dump fuse message (W): %s",
+ strerror (errno));
+
+ /*
+ * Return value reflects check on write to /dev/fuse,
+ * so ignore issues with dumping.
+ */
+
+ return 0;
+}
+
/*
* iov_out should contain a fuse_out_header at zeroth position.
* The error value of this header is sent to kernel.
@@ -224,35 +277,7 @@ send_fuse_iov (xlator_t *this, fuse_in_header_t *finh, struct iovec *iov_out,
gf_log ("glusterfs-fuse", GF_LOG_TRACE, "writev() result %d/%d %s",
res, fouh->len, res == -1 ? strerror (errno) : "");
- if (res == -1)
- return errno;
- if (res != fouh->len)
- return EINVAL;
-
- if (priv->fuse_dump_fd != -1) {
- char w = 'W';
- struct iovec diov[4] = {{0,},};
- uint32_t fusedump_item_count = 3;
- struct fusedump_timespec fts = {0,};
- struct fusedump_signature fsig = {0,};
-
- fusedump_setup_meta (diov, &w, &fusedump_item_count,
- &fts, &fsig);
-
- pthread_mutex_lock (&priv->fuse_dump_mutex);
- res = sys_writev (priv->fuse_dump_fd, diov,
- sizeof (diov)/sizeof (diov[0]));
- if (res != -1)
- res = sys_writev (priv->fuse_dump_fd, iov_out, count);
- pthread_mutex_unlock (&priv->fuse_dump_mutex);
-
- if (res == -1)
- gf_log ("glusterfs-fuse", GF_LOG_ERROR,
- "failed to dump fuse message (W): %s",
- strerror (errno));
- }
-
- return 0;
+ return check_and_dump_fuse_W (priv, iov_out, count, res);
}
static int
@@ -3981,6 +4006,7 @@ notify_kernel_loop (void *data)
fuse_invalidate_node_t *node = NULL;
fuse_invalidate_node_t *tmp = NULL;
struct fuse_out_header *pfoh = NULL;
+ struct iovec iov_out = {0,};
this = data;
priv = this->private;
@@ -4013,7 +4039,10 @@ notify_kernel_loop (void *data)
* the risk of stalling the insn pipeline.
*/
- rv = sys_write (priv->fd, node->inval_buf, len);
+ iov_out.iov_base = node->inval_buf;
+ iov_out.iov_len = len;
+ rv = sys_writev (priv->fd, &iov_out, 1);
+ check_and_dump_fuse_W (priv, &iov_out, 1, rv);
GF_FREE (node);