return 0;
}
+static void cusexmp_init(void *userdata, struct fuse_conn_info *conn)
+{
+ (void)userdata;
+
+ /* Disable the receiving and processing of FUSE_INTERRUPT requests */
+ conn->no_interrupt = 1;
+}
+
static void cusexmp_open(fuse_req_t req, struct fuse_file_info *fi)
{
fuse_reply_open(req, fi);
}
static const struct cuse_lowlevel_ops cusexmp_clop = {
+ .init = cusexmp_init,
.open = cusexmp_open,
.read = cusexmp_read,
.write = cusexmp_write,
return 0;
}
+static void hello_ll_init(void *userdata, struct fuse_conn_info *conn)
+{
+ (void)userdata;
+
+ /* Disable the receiving and processing of FUSE_INTERRUPT requests */
+ conn->no_interrupt = 1;
+}
+
static void hello_ll_getattr(fuse_req_t req, fuse_ino_t ino,
struct fuse_file_info *fi)
{
}
static const struct fuse_lowlevel_ops hello_ll_oper = {
+ .init = hello_ll_init,
.lookup = hello_ll_lookup,
.getattr = hello_ll_getattr,
.readdir = hello_ll_readdir,
fuse_reply_attr(req, &stbuf, 1.0);
}
+static void hello_ll_init(void *userdata, struct fuse_conn_info *conn)
+{
+ (void)userdata;
+
+ /* Disable the receiving and processing of FUSE_INTERRUPT requests */
+ conn->no_interrupt = 1;
+}
+
static void hello_ll_lookup(fuse_req_t req, fuse_ino_t parent, const char *name)
{
struct fuse_entry_param e;
}
static const struct fuse_lowlevel_ops hello_ll_oper = {
+ .init = hello_ll_init,
.lookup = hello_ll_lookup,
.getattr = hello_ll_getattr,
.readdir = hello_ll_readdir,
return 0;
}
+static void tfs_init(void *userdata, struct fuse_conn_info *conn) {
+ (void)userdata;
+
+ /* Disable the receiving and processing of FUSE_INTERRUPT requests */
+ conn->no_interrupt = 1;
+}
+
static void tfs_lookup(fuse_req_t req, fuse_ino_t parent,
const char *name) {
struct fuse_entry_param e;
}
static const struct fuse_lowlevel_ops tfs_oper = {
+ .init = tfs_init,
.lookup = tfs_lookup,
.getattr = tfs_getattr,
.readdir = tfs_readdir,
return 0;
}
+static void tfs_init(void *userdata, struct fuse_conn_info *conn) {
+ (void)userdata;
+
+ /* Disable the receiving and processing of FUSE_INTERRUPT requests */
+ conn->no_interrupt = 1;
+}
+
static void tfs_destroy(void *userarg)
{
(void)userarg;
}
static const struct fuse_lowlevel_ops tfs_oper = {
+ .init = tfs_init,
.destroy = tfs_destroy,
.lookup = tfs_lookup,
.getattr = tfs_getattr,
return 0;
}
+static void tfs_init(void *userdata, struct fuse_conn_info *conn) {
+ (void)userdata;
+
+ /* Disable the receiving and processing of FUSE_INTERRUPT requests */
+ conn->no_interrupt = 1;
+}
+
static void tfs_lookup(fuse_req_t req, fuse_ino_t parent,
const char *name) {
struct fuse_entry_param e;
static const struct fuse_lowlevel_ops tfs_oper = {
+ .init = tfs_init,
.lookup = tfs_lookup,
.getattr = tfs_getattr,
.readdir = tfs_readdir,
/* This is a local file system - no network coherency needed */
if (conn->capable & FUSE_CAP_DIRECT_IO_ALLOW_MMAP)
conn->want |= FUSE_CAP_DIRECT_IO_ALLOW_MMAP;
+
+ /* Disable the receiving and processing of FUSE_INTERRUPT requests */
+ conn->no_interrupt = 1;
}
fuse_log(FUSE_LOG_DEBUG, "lo_init: activating flock locks\n");
conn->want |= FUSE_CAP_FLOCK_LOCKS;
}
+
+ /* Disable the receiving and processing of FUSE_INTERRUPT requests */
+ conn->no_interrupt = 1;
}
static void lo_destroy(void *userdata)
#define FUSE_BACKING_STACKED_OVER (1)
unsigned max_backing_stack_depth;
+ /**
+ * Disable FUSE_INTERRUPT requests.
+ *
+ * Enable `no_interrupt` option to:
+ * 1) Avoid unnecessary locking operations and list operations,
+ * 2) Return ENOSYS for the reply of FUSE_INTERRUPT request to
+ * inform the kernel not to send the FUSE_INTERRUPT request.
+ */
+ unsigned no_interrupt;
+
/**
* For future use.
*/
- unsigned reserved[21];
+ unsigned reserved[20];
};
struct fuse_session;
if(conn->capable & FUSE_CAP_EXPORT_SUPPORT)
conn->want |= FUSE_CAP_EXPORT_SUPPORT;
fuse_fs_init(f->fs, conn, &f->conf);
+
+ /* Disable the receiving and processing of FUSE_INTERRUPT requests */
+ if (!f->conf.intr)
+ conn->no_interrupt = 1;
}
void fuse_fs_destroy(struct fuse_fs *fs)
int ctr;
struct fuse_session *se = req->se;
- pthread_mutex_lock(&se->lock);
- req->u.ni.func = NULL;
- req->u.ni.data = NULL;
- list_del_req(req);
- ctr = --req->ctr;
- fuse_chan_put(req->ch);
- req->ch = NULL;
- pthread_mutex_unlock(&se->lock);
+ if (se->conn.no_interrupt) {
+ ctr = --req->ctr;
+ fuse_chan_put(req->ch);
+ req->ch = NULL;
+ } else {
+ pthread_mutex_lock(&se->lock);
+ req->u.ni.func = NULL;
+ req->u.ni.data = NULL;
+ list_del_req(req);
+ ctr = --req->ctr;
+ fuse_chan_put(req->ch);
+ req->ch = NULL;
+ pthread_mutex_unlock(&se->lock);
+ }
if (!ctr)
destroy_req(req);
}
err = ENOSYS;
if (in->opcode >= FUSE_MAXOP || !fuse_ll_ops[in->opcode].func)
goto reply_err;
- if (in->opcode != FUSE_INTERRUPT) {
+ /* Do not process interrupt request */
+ if (se->conn.no_interrupt && in->opcode == FUSE_INTERRUPT) {
+ if (se->debug)
+ fuse_log(FUSE_LOG_DEBUG, "FUSE_INTERRUPT: reply to kernel to disable interrupt\n");
+ goto reply_err;
+ }
+ if (!se->conn.no_interrupt && in->opcode != FUSE_INTERRUPT) {
struct fuse_req *intr;
pthread_mutex_lock(&se->lock);
intr = check_interrupt(se, req);