summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJean-Pierre André <jpandre@users.sourceforge.net>2012-08-22 10:00:21 +0200
committerJean-Pierre André <jpandre@users.sourceforge.net>2012-08-22 10:00:21 +0200
commitcd8b716a67d07a4278f1d8305ab0493d1873d885 (patch)
treedd794e1dbad03eaadb84f2276812c880dabdd36c
parent5c5174322bd32ffc52fb1aa65964290bace05f7d (diff)
downloadillumos-fusefs-cd8b716a67d07a4278f1d8305ab0493d1873d885.tar.gz
Deleted sent messages when no reply is expected
-rw-r--r--kernel/fuse_dev.c24
-rw-r--r--kernel/fuse_queue.h2
-rw-r--r--kernel/fuse_vnops.c1
3 files changed, 25 insertions, 2 deletions
diff --git a/kernel/fuse_dev.c b/kernel/fuse_dev.c
index 50f29af..6f38d9f 100644
--- a/kernel/fuse_dev.c
+++ b/kernel/fuse_dev.c
@@ -21,6 +21,8 @@
/*
* Copyright 2009 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
+ *
+ * Portions Copyright 2012 Jean-Pierre Andre
*/
/*
@@ -369,6 +371,7 @@ fuse_dev_write(dev_t dev, struct uio *uiop, cred_t *cred_p)
struct fuse_out_header *outh;
fuse_session_t *se_p;
fuse_msg_node_t *msg_p = NULL;
+ fuse_msg_node_t *msg_next;
minor_t ndx = getminor(dev);
struct fuse_iov *iovbuf;
@@ -414,8 +417,7 @@ fuse_dev_write(dev_t dev, struct uio *uiop, cred_t *cred_p)
/* Reset error before starting the search */
err = DDI_FAILURE;
- for (msg_p = list_head(&(se_p->msg_list)); msg_p;
- msg_p = list_next(&(se_p->msg_list), msg_p)) {
+ for (msg_p = list_head(&(se_p->msg_list)); msg_p; ) {
if (msg_p->fmn_unique == outh->unique) {
if (msg_p->fmn_state == FUSE_MSG_STATE_READ) {
msg_p->fmn_state = FUSE_MSG_STATE_WRITE;
@@ -430,6 +432,24 @@ fuse_dev_write(dev_t dev, struct uio *uiop, cred_t *cred_p)
FUSE_SESSION_MUTEX_UNLOCK(se_p);
goto cleanup;
}
+ msg_p = list_next(&(se_p->msg_list), msg_p);
+ } else {
+ msg_next = list_next(&(se_p->msg_list), msg_p);
+ /*
+ * if no callback handler is registered, and no
+ * reply is expected, it is our responsibility
+ * to free up obsolete message nodes.
+ */
+ if (!msg_p->frd_on_request_complete
+ && msg_p->fmn_noreply) {
+ if (msg_p->fmn_unique < se_p->max_unique) {
+ list_remove(&(se_p->msg_list), msg_p);
+ fuse_free_msg(msg_p);
+ }
+ if (outh->unique > se_p->max_unique)
+ se_p->max_unique = outh->unique;
+ }
+ msg_p = msg_next;
}
}
FUSE_SESSION_MUTEX_UNLOCK(se_p);
diff --git a/kernel/fuse_queue.h b/kernel/fuse_queue.h
index 5a0b8d3..251dbb0 100644
--- a/kernel/fuse_queue.h
+++ b/kernel/fuse_queue.h
@@ -54,6 +54,7 @@ typedef struct fuse_session
minor_t minor; /* Minor number associated with this session */
uint32_t state;
uint64_t unique; /* msg id used between lib and kernel module */
+ uint64_t max_unique;
cred_t *usercred; /* Credentials passed by fuse library */
uint32_t max_write; /* Max Write value set by fuse lib */
vfs_t *vfs;
@@ -109,6 +110,7 @@ struct fuse_msg_node
kcondvar_t fmn_cv;
kmutex_t fmn_mutx;
int fmn_state;
+ int fmn_noreply; /* no reply expected */
uint64_t fmn_unique; /* identifies a unique message */
/* Message interchange struct between FUSE Kernel and FUSE lib. */
fuse_req_data_t fmn_req;
diff --git a/kernel/fuse_vnops.c b/kernel/fuse_vnops.c
index ffb2310..7d73fdc 100644
--- a/kernel/fuse_vnops.c
+++ b/kernel/fuse_vnops.c
@@ -3125,6 +3125,7 @@ fuse_send_forget(uint64_t nodeid, fuse_session_t *sep, uint64_t nlookup)
ffi->nlookup = nlookup;
/* Send the request to the fuse daemon and return */
+ msgp->fmn_noreply = 1;
fuse_queue_request_nowait(sep, msgp);
}