|
|
14f8ab |
From e2af9793014ad67859aa73088765a52307cbe466 Mon Sep 17 00:00:00 2001
|
|
|
14f8ab |
From: Csaba Henk <csaba@redhat.com>
|
|
|
14f8ab |
Date: Tue, 7 Jan 2020 19:43:05 +0100
|
|
|
14f8ab |
Subject: [PATCH 346/346] fuse: degrade logging of write failure to fuse device
|
|
|
14f8ab |
|
|
|
14f8ab |
Problem:
|
|
|
14f8ab |
|
|
|
14f8ab |
FUSE uses failures of communicating with /dev/fuse with various
|
|
|
14f8ab |
errnos to indicate in-kernel conditions to userspace. Some of these
|
|
|
14f8ab |
shouldn't be handled as an application error. Also the standard
|
|
|
14f8ab |
POSIX errno description should not be shown as they are misleading
|
|
|
14f8ab |
in this context.
|
|
|
14f8ab |
|
|
|
14f8ab |
Solution:
|
|
|
14f8ab |
|
|
|
14f8ab |
When writing to the fuse device, the caller of the respective
|
|
|
14f8ab |
convenience routine can mask those errnos which don't qualify to
|
|
|
14f8ab |
be an error for the application in that context, so then those
|
|
|
14f8ab |
shall be reported at DEBUG level.
|
|
|
14f8ab |
|
|
|
14f8ab |
The possible non-standard errnos are reported with their
|
|
|
14f8ab |
POSIX name instead of their description to avoid confusion.
|
|
|
14f8ab |
(Eg. for ENOENT we don't log "no such file or directory",
|
|
|
14f8ab |
we log indeed literal "ENOENT".)
|
|
|
14f8ab |
|
|
|
14f8ab |
Upstream on https://review.gluster.org/23974
|
|
|
14f8ab |
> Change-Id: I510158843e4b1d482bdc496c2e97b1860dc1ba93
|
|
|
14f8ab |
> updates: bz#1193929
|
|
|
14f8ab |
> Signed-off-by: Csaba Henk <csaba@redhat.com>
|
|
|
14f8ab |
|
|
|
14f8ab |
BUG: 1763208
|
|
|
14f8ab |
Change-Id: Ib1676bb334ed153ce74ae1c0413fc0e58fb388c7
|
|
|
14f8ab |
Signed-off-by: Csaba Henk <csaba@redhat.com>
|
|
|
14f8ab |
Reviewed-on: https://code.engineering.redhat.com/gerrit/189056
|
|
|
14f8ab |
Tested-by: RHGS Build Bot <nigelb@redhat.com>
|
|
|
14f8ab |
Reviewed-by: Sunil Kumar Heggodu Gopala Acharya <sheggodu@redhat.com>
|
|
|
14f8ab |
---
|
|
|
14f8ab |
xlators/mount/fuse/src/fuse-bridge.c | 78 +++++++++++++++++++++++++++++++++---
|
|
|
14f8ab |
xlators/mount/fuse/src/fuse-bridge.h | 9 ++++-
|
|
|
14f8ab |
2 files changed, 80 insertions(+), 7 deletions(-)
|
|
|
14f8ab |
|
|
|
14f8ab |
diff --git a/xlators/mount/fuse/src/fuse-bridge.c b/xlators/mount/fuse/src/fuse-bridge.c
|
|
|
14f8ab |
index ebe5c28..6e99053 100644
|
|
|
14f8ab |
--- a/xlators/mount/fuse/src/fuse-bridge.c
|
|
|
14f8ab |
+++ b/xlators/mount/fuse/src/fuse-bridge.c
|
|
|
14f8ab |
@@ -198,7 +198,7 @@ fusedump_setup_meta(struct iovec *iovs, char *dir,
|
|
|
14f8ab |
|
|
|
14f8ab |
static int
|
|
|
14f8ab |
check_and_dump_fuse_W(fuse_private_t *priv, struct iovec *iov_out, int count,
|
|
|
14f8ab |
- ssize_t res)
|
|
|
14f8ab |
+ ssize_t res, errnomask_t errnomask)
|
|
|
14f8ab |
{
|
|
|
14f8ab |
char w = 'W';
|
|
|
14f8ab |
struct iovec diov[4] = {
|
|
|
14f8ab |
@@ -216,8 +216,59 @@ check_and_dump_fuse_W(fuse_private_t *priv, struct iovec *iov_out, int count,
|
|
|
14f8ab |
struct fuse_out_header *fouh = NULL;
|
|
|
14f8ab |
|
|
|
14f8ab |
if (res == -1) {
|
|
|
14f8ab |
- gf_log_callingfn("glusterfs-fuse", GF_LOG_ERROR,
|
|
|
14f8ab |
- "writing to fuse device failed: %s", strerror(errno));
|
|
|
14f8ab |
+ const char *errdesc = NULL;
|
|
|
14f8ab |
+ gf_loglevel_t loglevel = GF_LOG_ERROR;
|
|
|
14f8ab |
+
|
|
|
14f8ab |
+ /* If caller masked the errno, then it
|
|
|
14f8ab |
+ * does not indicate an error at the application
|
|
|
14f8ab |
+ * level, so we degrade the log severity to DEBUG.
|
|
|
14f8ab |
+ */
|
|
|
14f8ab |
+ if (errnomask && errno < ERRNOMASK_MAX &&
|
|
|
14f8ab |
+ GET_ERRNO_MASK(errnomask, errno))
|
|
|
14f8ab |
+ loglevel = GF_LOG_DEBUG;
|
|
|
14f8ab |
+
|
|
|
14f8ab |
+ switch (errno) {
|
|
|
14f8ab |
+ /* The listed errnos are FUSE status indicators,
|
|
|
14f8ab |
+ * not legit values according to POSIX (see write(3p)),
|
|
|
14f8ab |
+ * so resolving them according to the standard
|
|
|
14f8ab |
+ * POSIX interpretation would be misleading.
|
|
|
14f8ab |
+ */
|
|
|
14f8ab |
+ case ENOENT:
|
|
|
14f8ab |
+ errdesc = "ENOENT";
|
|
|
14f8ab |
+ break;
|
|
|
14f8ab |
+ case ENOTDIR:
|
|
|
14f8ab |
+ errdesc = "ENOTDIR";
|
|
|
14f8ab |
+ break;
|
|
|
14f8ab |
+ case ENODEV:
|
|
|
14f8ab |
+ errdesc = "ENODEV";
|
|
|
14f8ab |
+ break;
|
|
|
14f8ab |
+ case EPERM:
|
|
|
14f8ab |
+ errdesc = "EPERM";
|
|
|
14f8ab |
+ break;
|
|
|
14f8ab |
+ case ENOMEM:
|
|
|
14f8ab |
+ errdesc = "ENOMEM";
|
|
|
14f8ab |
+ break;
|
|
|
14f8ab |
+ case ENOTCONN:
|
|
|
14f8ab |
+ errdesc = "ENOTCONN";
|
|
|
14f8ab |
+ break;
|
|
|
14f8ab |
+ case ECONNREFUSED:
|
|
|
14f8ab |
+ errdesc = "ECONNREFUSED";
|
|
|
14f8ab |
+ break;
|
|
|
14f8ab |
+ case EOVERFLOW:
|
|
|
14f8ab |
+ errdesc = "EOVERFLOW";
|
|
|
14f8ab |
+ break;
|
|
|
14f8ab |
+ case EBUSY:
|
|
|
14f8ab |
+ errdesc = "EBUSY";
|
|
|
14f8ab |
+ break;
|
|
|
14f8ab |
+ case ENOTEMPTY:
|
|
|
14f8ab |
+ errdesc = "ENOTEMPTY";
|
|
|
14f8ab |
+ break;
|
|
|
14f8ab |
+ default:
|
|
|
14f8ab |
+ errdesc = strerror(errno);
|
|
|
14f8ab |
+ }
|
|
|
14f8ab |
+
|
|
|
14f8ab |
+ gf_log_callingfn("glusterfs-fuse", loglevel,
|
|
|
14f8ab |
+ "writing to fuse device failed: %s", errdesc);
|
|
|
14f8ab |
return errno;
|
|
|
14f8ab |
}
|
|
|
14f8ab |
|
|
|
14f8ab |
@@ -282,7 +333,7 @@ send_fuse_iov(xlator_t *this, fuse_in_header_t *finh, struct iovec *iov_out,
|
|
|
14f8ab |
gf_log("glusterfs-fuse", GF_LOG_TRACE, "writev() result %d/%d %s", res,
|
|
|
14f8ab |
fouh->len, res == -1 ? strerror(errno) : "");
|
|
|
14f8ab |
|
|
|
14f8ab |
- return check_and_dump_fuse_W(priv, iov_out, count, res);
|
|
|
14f8ab |
+ return check_and_dump_fuse_W(priv, iov_out, count, res, NULL);
|
|
|
14f8ab |
}
|
|
|
14f8ab |
|
|
|
14f8ab |
static int
|
|
|
14f8ab |
@@ -353,6 +404,15 @@ fuse_invalidate_entry(xlator_t *this, uint64_t fuse_ino)
|
|
|
14f8ab |
fouh->unique = 0;
|
|
|
14f8ab |
fouh->error = FUSE_NOTIFY_INVAL_ENTRY;
|
|
|
14f8ab |
|
|
|
14f8ab |
+ if (ENOENT < ERRNOMASK_MAX)
|
|
|
14f8ab |
+ MASK_ERRNO(node->errnomask, ENOENT);
|
|
|
14f8ab |
+ if (ENOTDIR < ERRNOMASK_MAX)
|
|
|
14f8ab |
+ MASK_ERRNO(node->errnomask, ENOTDIR);
|
|
|
14f8ab |
+ if (EBUSY < ERRNOMASK_MAX)
|
|
|
14f8ab |
+ MASK_ERRNO(node->errnomask, EBUSY);
|
|
|
14f8ab |
+ if (ENOTEMPTY < ERRNOMASK_MAX)
|
|
|
14f8ab |
+ MASK_ERRNO(node->errnomask, ENOTEMPTY);
|
|
|
14f8ab |
+
|
|
|
14f8ab |
if (dentry->name) {
|
|
|
14f8ab |
nlen = strlen(dentry->name);
|
|
|
14f8ab |
fouh->len = sizeof(*fouh) + sizeof(*fnieo) + nlen + 1;
|
|
|
14f8ab |
@@ -437,6 +497,9 @@ fuse_invalidate_inode(xlator_t *this, uint64_t fuse_ino)
|
|
|
14f8ab |
fniio->off = 0;
|
|
|
14f8ab |
fniio->len = -1;
|
|
|
14f8ab |
|
|
|
14f8ab |
+ if (ENOENT < ERRNOMASK_MAX)
|
|
|
14f8ab |
+ MASK_ERRNO(node->errnomask, ENOENT);
|
|
|
14f8ab |
+
|
|
|
14f8ab |
fuse_log_eh(this, "Invalidated inode %" PRIu64 " (gfid: %s)", fuse_ino,
|
|
|
14f8ab |
uuid_utoa(inode->gfid));
|
|
|
14f8ab |
gf_log("glusterfs-fuse", GF_LOG_TRACE,
|
|
|
14f8ab |
@@ -482,6 +545,7 @@ fuse_timed_message_new(void)
|
|
|
14f8ab |
/* should be NULL if not set */
|
|
|
14f8ab |
dmsg->fuse_message_body = NULL;
|
|
|
14f8ab |
INIT_LIST_HEAD(&dmsg->next);
|
|
|
14f8ab |
+ memset(dmsg->errnomask, 0, sizeof(dmsg->errnomask));
|
|
|
14f8ab |
|
|
|
14f8ab |
return dmsg;
|
|
|
14f8ab |
}
|
|
|
14f8ab |
@@ -680,6 +744,8 @@ fuse_interrupt(xlator_t *this, fuse_in_header_t *finh, void *msg,
|
|
|
14f8ab |
dmsg->fuse_out_header.unique = finh->unique;
|
|
|
14f8ab |
dmsg->fuse_out_header.len = sizeof(dmsg->fuse_out_header);
|
|
|
14f8ab |
dmsg->fuse_out_header.error = -EAGAIN;
|
|
|
14f8ab |
+ if (ENOENT < ERRNOMASK_MAX)
|
|
|
14f8ab |
+ MASK_ERRNO(dmsg->errnomask, ENOENT);
|
|
|
14f8ab |
timespec_now(&dmsg->scheduled_ts);
|
|
|
14f8ab |
timespec_adjust_delta(&dmsg->scheduled_ts,
|
|
|
14f8ab |
(struct timespec){0, 10000000});
|
|
|
14f8ab |
@@ -4848,7 +4914,7 @@ notify_kernel_loop(void *data)
|
|
|
14f8ab |
iov_out.iov_base = node->inval_buf;
|
|
|
14f8ab |
iov_out.iov_len = len;
|
|
|
14f8ab |
rv = sys_writev(priv->fd, &iov_out, 1);
|
|
|
14f8ab |
- check_and_dump_fuse_W(priv, &iov_out, 1, rv);
|
|
|
14f8ab |
+ check_and_dump_fuse_W(priv, &iov_out, 1, rv, node->errnomask);
|
|
|
14f8ab |
|
|
|
14f8ab |
GF_FREE(node);
|
|
|
14f8ab |
|
|
|
14f8ab |
@@ -4940,7 +5006,7 @@ timed_response_loop(void *data)
|
|
|
14f8ab |
iovs[1] = (struct iovec){dmsg->fuse_message_body,
|
|
|
14f8ab |
len - sizeof(struct fuse_out_header)};
|
|
|
14f8ab |
rv = sys_writev(priv->fd, iovs, 2);
|
|
|
14f8ab |
- check_and_dump_fuse_W(priv, iovs, 2, rv);
|
|
|
14f8ab |
+ check_and_dump_fuse_W(priv, iovs, 2, rv, dmsg->errnomask);
|
|
|
14f8ab |
|
|
|
14f8ab |
fuse_timed_message_free(dmsg);
|
|
|
14f8ab |
|
|
|
14f8ab |
diff --git a/xlators/mount/fuse/src/fuse-bridge.h b/xlators/mount/fuse/src/fuse-bridge.h
|
|
|
14f8ab |
index cf4479c..d2d462c 100644
|
|
|
14f8ab |
--- a/xlators/mount/fuse/src/fuse-bridge.h
|
|
|
14f8ab |
+++ b/xlators/mount/fuse/src/fuse-bridge.h
|
|
|
14f8ab |
@@ -195,14 +195,20 @@ struct fuse_private {
|
|
|
14f8ab |
};
|
|
|
14f8ab |
typedef struct fuse_private fuse_private_t;
|
|
|
14f8ab |
|
|
|
14f8ab |
+typedef uint64_t errnomask_t[2];
|
|
|
14f8ab |
+#define MASK_ERRNO(mask, n) ((mask)[(n) >> 6] |= ((uint64_t)1 << ((n)&63)))
|
|
|
14f8ab |
+#define GET_ERRNO_MASK(mask, n) ((mask)[(n) >> 6] & ((uint64_t)1 << ((n)&63)))
|
|
|
14f8ab |
+#define ERRNOMASK_MAX (64 * (sizeof(errnomask_t) / sizeof(uint64_t)))
|
|
|
14f8ab |
+
|
|
|
14f8ab |
#define INVAL_BUF_SIZE \
|
|
|
14f8ab |
(sizeof(struct fuse_out_header) + \
|
|
|
14f8ab |
max(sizeof(struct fuse_notify_inval_inode_out), \
|
|
|
14f8ab |
sizeof(struct fuse_notify_inval_entry_out) + NAME_MAX + 1))
|
|
|
14f8ab |
|
|
|
14f8ab |
struct fuse_invalidate_node {
|
|
|
14f8ab |
- char inval_buf[INVAL_BUF_SIZE];
|
|
|
14f8ab |
+ errnomask_t errnomask;
|
|
|
14f8ab |
struct list_head next;
|
|
|
14f8ab |
+ char inval_buf[INVAL_BUF_SIZE];
|
|
|
14f8ab |
};
|
|
|
14f8ab |
typedef struct fuse_invalidate_node fuse_invalidate_node_t;
|
|
|
14f8ab |
|
|
|
14f8ab |
@@ -210,6 +216,7 @@ struct fuse_timed_message {
|
|
|
14f8ab |
struct fuse_out_header fuse_out_header;
|
|
|
14f8ab |
void *fuse_message_body;
|
|
|
14f8ab |
struct timespec scheduled_ts;
|
|
|
14f8ab |
+ errnomask_t errnomask;
|
|
|
14f8ab |
struct list_head next;
|
|
|
14f8ab |
};
|
|
|
14f8ab |
typedef struct fuse_timed_message fuse_timed_message_t;
|
|
|
14f8ab |
--
|
|
|
14f8ab |
1.8.3.1
|
|
|
14f8ab |
|