summaryrefslogtreecommitdiffstats
path: root/xlators/mount
diff options
context:
space:
mode:
authorCsaba Henk <csaba@redhat.com>2018-08-21 12:44:54 +0200
committerAmar Tumballi <amarts@redhat.com>2018-11-06 04:21:57 +0000
commit4c6b063463ae48b3509ff8e66cd391f8637a86af (patch)
tree267710e0564138d8e6072aaa229f28f44626bf88 /xlators/mount
parentbceb9f25671e65cb2f0987a84370055e7c36900f (diff)
fuse: diagnostic FLUSH interrupt
We add dummy interrupt handling for the FLUSH fuse message. It can be enabled by the "--fuse-flush-handle-interrupt" hidden command line option, or "-ofuse-flush-handle-interrupt=yes" mount option. It serves no other than diagnostic & demonstational purposes -- to exercise the interrupt handling framework a bit and to give an usage example. Documentation is also provided that showcases interrupt handling via FLUSH. Change-Id: I522f1e798501d06b74ac3592a5f73c1ab0590c60 updates: #465 Signed-off-by: Csaba Henk <csaba@redhat.com>
Diffstat (limited to 'xlators/mount')
-rw-r--r--xlators/mount/fuse/src/fuse-bridge.c60
-rw-r--r--xlators/mount/fuse/src/fuse-bridge.h4
-rwxr-xr-xxlators/mount/fuse/utils/mount.glusterfs.in7
3 files changed, 69 insertions, 2 deletions
diff --git a/xlators/mount/fuse/src/fuse-bridge.c b/xlators/mount/fuse/src/fuse-bridge.c
index e4e894e6c9b..48b8d9df480 100644
--- a/xlators/mount/fuse/src/fuse-bridge.c
+++ b/xlators/mount/fuse/src/fuse-bridge.c
@@ -1829,6 +1829,21 @@ fuse_err_cbk(call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret,
}
static int
+fuse_flush_cbk(call_frame_t *frame, void *cookie, xlator_t *this,
+ int32_t op_ret, int32_t op_errno, dict_t *xdata)
+{
+ fuse_private_t *priv = this->private;
+
+ if (priv->flush_handle_interrupt) {
+ if (fuse_interrupt_finish_fop(frame, this, _gf_false, NULL)) {
+ return 0;
+ }
+ }
+
+ return fuse_err_cbk(frame, cookie, this, op_ret, op_errno, xdata);
+}
+
+static int
fuse_fsync_cbk(call_frame_t *frame, void *cookie, xlator_t *this,
int32_t op_ret, int32_t op_errno, struct iatt *prebuf,
struct iatt *postbuf, dict_t *xdata)
@@ -3044,7 +3059,19 @@ fuse_lseek(xlator_t *this, fuse_in_header_t *finh, void *msg,
void
fuse_flush_resume(fuse_state_t *state)
{
- FUSE_FOP(state, fuse_err_cbk, GF_FOP_FLUSH, flush, state->fd, state->xdata);
+ FUSE_FOP(state, fuse_flush_cbk, GF_FOP_FLUSH, flush, state->fd,
+ state->xdata);
+}
+
+static void
+fuse_flush_interrupt_handler(xlator_t *this, fuse_interrupt_record_t *fir)
+{
+ gf_log("glusterfs-fuse", GF_LOG_DEBUG,
+ "FLUSH unique %" PRIu64 ": interrupt handler triggered",
+ fir->fuse_in_header.unique);
+
+ fuse_interrupt_finish_interrupt(this, fir, INTERRUPT_HANDLED, _gf_false,
+ NULL);
}
static void
@@ -3052,6 +3079,7 @@ fuse_flush(xlator_t *this, fuse_in_header_t *finh, void *msg,
struct iobuf *iobuf)
{
struct fuse_flush_in *ffi = msg;
+ fuse_private_t *priv = NULL;
fuse_state_t *state = NULL;
fd_t *fd = NULL;
@@ -3060,6 +3088,26 @@ fuse_flush(xlator_t *this, fuse_in_header_t *finh, void *msg,
fd = FH_TO_FD(ffi->fh);
state->fd = fd;
+ priv = this->private;
+ if (priv->flush_handle_interrupt) {
+ fuse_interrupt_record_t *fir = NULL;
+
+ fir = fuse_interrupt_record_new(finh, fuse_flush_interrupt_handler);
+ if (!fir) {
+ send_fuse_err(this, finh, ENOMEM);
+
+ gf_log("glusterfs-fuse", GF_LOG_ERROR,
+ "FLUSH unique %" PRIu64
+ ":"
+ " interrupt record allocation failed",
+ finh->unique);
+ free_fuse_state(state);
+
+ return;
+ }
+ fuse_interrupt_record_insert(this, fir);
+ }
+
fuse_resolve_fd_init(state, &state->resolve, fd);
state->lk_owner = ffi->lock_owner;
@@ -6301,6 +6349,9 @@ init(xlator_t *this_xl)
GF_OPTION_INIT("attr-times-granularity", priv->attr_times_granularity,
int32, cleanup_exit);
+ GF_OPTION_INIT("flush-handle-interrupt", priv->flush_handle_interrupt, bool,
+ cleanup_exit);
+
/* user has set only background-qlen, not congestion-threshold,
use the fuse kernel driver formula to set congestion. ie, 75% */
if (dict_get(this_xl->options, "background-qlen") &&
@@ -6608,5 +6659,12 @@ struct volume_options options[] = {
.max = 1000000000,
.description = "Supported granularity of file attribute times.",
},
+ {
+ .key = {"flush-handle-interrupt"},
+ .type = GF_OPTION_TYPE_BOOL,
+ .default_value = "false",
+ .description =
+ "Handle iterrupts in FLUSH handler (for testing purposes).",
+ },
{.key = {NULL}},
};
diff --git a/xlators/mount/fuse/src/fuse-bridge.h b/xlators/mount/fuse/src/fuse-bridge.h
index b391af76bac..b997d9e0cbb 100644
--- a/xlators/mount/fuse/src/fuse-bridge.h
+++ b/xlators/mount/fuse/src/fuse-bridge.h
@@ -161,6 +161,8 @@ struct fuse_private {
/* Interrupt subscription */
struct list_head interrupt_list;
pthread_mutex_t interrupt_mutex;
+
+ gf_boolean_t flush_handle_interrupt;
};
typedef struct fuse_private fuse_private_t;
@@ -194,7 +196,7 @@ typedef struct fuse_interrupt_record fuse_interrupt_record_t;
typedef void (*fuse_interrupt_handler_t)(xlator_t *this,
fuse_interrupt_record_t *);
struct fuse_interrupt_record {
- struct fuse_in_header fuse_in_header;
+ fuse_in_header_t fuse_in_header;
void *data;
gf_boolean_t hit;
fuse_interrupt_state_t interrupt_state;
diff --git a/xlators/mount/fuse/utils/mount.glusterfs.in b/xlators/mount/fuse/utils/mount.glusterfs.in
index 40172fc421d..4a95cd80b87 100755
--- a/xlators/mount/fuse/utils/mount.glusterfs.in
+++ b/xlators/mount/fuse/utils/mount.glusterfs.in
@@ -281,6 +281,10 @@ start_glusterfs ()
cmd_line=$(echo "$cmd_line --dump-fuse=$dump_fuse");
fi
+ if [ -n "$fuse_flush_handle_interrupt" ]; then
+ cmd_line=$(echo "$cmd_line --fuse-flush-handle-interrupt=$fuse_flush_handle_interrupt");
+ fi
+
if [ -n "$process_name" ]; then
cmd_line=$(echo "$cmd_line --process-name fuse.$process_name");
else
@@ -541,6 +545,9 @@ with_options()
"dump-fuse")
dump_fuse=$value
;;
+ "fuse-flush-handle-interrupt")
+ fuse_flush_handle_interrupt=$value
+ ;;
"context"|"fscontext"|"defcontext"|"rootcontext")
# standard SElinux mount options to pass to the kernel
[ -z "$fuse_mountopts" ] || fuse_mountopts="$fuse_mountopts,"