summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--fs/fuse/fuse_i.h24
-rw-r--r--fs/fuse/inode.c2
2 files changed, 23 insertions, 3 deletions
diff --git a/fs/fuse/fuse_i.h b/fs/fuse/fuse_i.h
index 7ed1d3c53b8a..46cf933aa3bf 100644
--- a/fs/fuse/fuse_i.h
+++ b/fs/fuse/fuse_i.h
@@ -94,6 +94,11 @@ struct fuse_out {
/** Header returned from userspace */
struct fuse_out_header h;
+ /*
+ * The following bitfields are not changed during the request
+ * processing
+ */
+
/** Last argument is variable length (can be shorter than
arg->size) */
unsigned argvar:1;
@@ -136,6 +141,12 @@ struct fuse_req {
/** refcount */
atomic_t count;
+ /*
+ * The following bitfields are either set once before the
+ * request is queued or setting/clearing them is protected by
+ * fuse_lock
+ */
+
/** True if the request has reply */
unsigned isreply:1;
@@ -250,15 +261,22 @@ struct fuse_conn {
u64 reqctr;
/** Mount is active */
- unsigned mounted : 1;
+ unsigned mounted;
/** Connection established, cleared on umount, connection
abort and device release */
- unsigned connected : 1;
+ unsigned connected;
- /** Connection failed (version mismatch) */
+ /** Connection failed (version mismatch). Cannot race with
+ setting other bitfields since it is only set once in INIT
+ reply, before any other request, and never cleared */
unsigned conn_error : 1;
+ /*
+ * The following bitfields are only for optimization purposes
+ * and hence races in setting them will not cause malfunction
+ */
+
/** Is fsync not implemented by fs? */
unsigned no_fsync : 1;
diff --git a/fs/fuse/inode.c b/fs/fuse/inode.c
index 8683e7254d53..c755a0440a66 100644
--- a/fs/fuse/inode.c
+++ b/fs/fuse/inode.c
@@ -397,6 +397,7 @@ static struct fuse_conn *new_conn(void)
init_rwsem(&fc->sbput_sem);
kobj_set_kset_s(fc, connections_subsys);
kobject_init(&fc->kobj);
+ atomic_set(&fc->num_waiting, 0);
for (i = 0; i < FUSE_MAX_OUTSTANDING; i++) {
struct fuse_req *req = fuse_request_alloc();
if (!req) {
@@ -492,6 +493,7 @@ static void fuse_send_init(struct fuse_conn *fc)
to be exactly one request available */
struct fuse_req *req = fuse_get_request(fc);
struct fuse_init_in *arg = &req->misc.init_in;
+
arg->major = FUSE_KERNEL_VERSION;
arg->minor = FUSE_KERNEL_MINOR_VERSION;
req->in.h.opcode = FUSE_INIT;