diff options
author | Csaba Henk <csaba@redhat.com> | 2018-01-16 00:37:45 +0100 |
---|---|---|
committer | Amar Tumballi <amarts@redhat.com> | 2018-01-17 00:00:40 +0000 |
commit | 1b2a3a417f62a7b2aa15918d7be449c243d96b94 (patch) | |
tree | e9fbe190d598910b8516ce8723765edbc2272624 /xlators/mount | |
parent | 9404b0de3fd8ab5adc3a531d4cb37b56e1e3908f (diff) |
fuse: write out reverse notification to fuse dump
BUG: 1534602
Change-Id: Ide42cf9cffe462d0cc46272b327c2a05999f09ba
Signed-off-by: Csaba Henk <csaba@redhat.com>
Diffstat (limited to 'xlators/mount')
-rw-r--r-- | xlators/mount/fuse/src/fuse-bridge.c | 89 |
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); |