diff options
-rw-r--r-- | fs/fuse/fuse_i.h | 24 | ||||
-rw-r--r-- | fs/fuse/inode.c | 2 |
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 { | |||
94 | /** Header returned from userspace */ | 94 | /** Header returned from userspace */ |
95 | struct fuse_out_header h; | 95 | struct fuse_out_header h; |
96 | 96 | ||
97 | /* | ||
98 | * The following bitfields are not changed during the request | ||
99 | * processing | ||
100 | */ | ||
101 | |||
97 | /** Last argument is variable length (can be shorter than | 102 | /** Last argument is variable length (can be shorter than |
98 | arg->size) */ | 103 | arg->size) */ |
99 | unsigned argvar:1; | 104 | unsigned argvar:1; |
@@ -136,6 +141,12 @@ struct fuse_req { | |||
136 | /** refcount */ | 141 | /** refcount */ |
137 | atomic_t count; | 142 | atomic_t count; |
138 | 143 | ||
144 | /* | ||
145 | * The following bitfields are either set once before the | ||
146 | * request is queued or setting/clearing them is protected by | ||
147 | * fuse_lock | ||
148 | */ | ||
149 | |||
139 | /** True if the request has reply */ | 150 | /** True if the request has reply */ |
140 | unsigned isreply:1; | 151 | unsigned isreply:1; |
141 | 152 | ||
@@ -250,15 +261,22 @@ struct fuse_conn { | |||
250 | u64 reqctr; | 261 | u64 reqctr; |
251 | 262 | ||
252 | /** Mount is active */ | 263 | /** Mount is active */ |
253 | unsigned mounted : 1; | 264 | unsigned mounted; |
254 | 265 | ||
255 | /** Connection established, cleared on umount, connection | 266 | /** Connection established, cleared on umount, connection |
256 | abort and device release */ | 267 | abort and device release */ |
257 | unsigned connected : 1; | 268 | unsigned connected; |
258 | 269 | ||
259 | /** Connection failed (version mismatch) */ | 270 | /** Connection failed (version mismatch). Cannot race with |
271 | setting other bitfields since it is only set once in INIT | ||
272 | reply, before any other request, and never cleared */ | ||
260 | unsigned conn_error : 1; | 273 | unsigned conn_error : 1; |
261 | 274 | ||
275 | /* | ||
276 | * The following bitfields are only for optimization purposes | ||
277 | * and hence races in setting them will not cause malfunction | ||
278 | */ | ||
279 | |||
262 | /** Is fsync not implemented by fs? */ | 280 | /** Is fsync not implemented by fs? */ |
263 | unsigned no_fsync : 1; | 281 | unsigned no_fsync : 1; |
264 | 282 | ||
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) | |||
397 | init_rwsem(&fc->sbput_sem); | 397 | init_rwsem(&fc->sbput_sem); |
398 | kobj_set_kset_s(fc, connections_subsys); | 398 | kobj_set_kset_s(fc, connections_subsys); |
399 | kobject_init(&fc->kobj); | 399 | kobject_init(&fc->kobj); |
400 | atomic_set(&fc->num_waiting, 0); | ||
400 | for (i = 0; i < FUSE_MAX_OUTSTANDING; i++) { | 401 | for (i = 0; i < FUSE_MAX_OUTSTANDING; i++) { |
401 | struct fuse_req *req = fuse_request_alloc(); | 402 | struct fuse_req *req = fuse_request_alloc(); |
402 | if (!req) { | 403 | if (!req) { |
@@ -492,6 +493,7 @@ static void fuse_send_init(struct fuse_conn *fc) | |||
492 | to be exactly one request available */ | 493 | to be exactly one request available */ |
493 | struct fuse_req *req = fuse_get_request(fc); | 494 | struct fuse_req *req = fuse_get_request(fc); |
494 | struct fuse_init_in *arg = &req->misc.init_in; | 495 | struct fuse_init_in *arg = &req->misc.init_in; |
496 | |||
495 | arg->major = FUSE_KERNEL_VERSION; | 497 | arg->major = FUSE_KERNEL_VERSION; |
496 | arg->minor = FUSE_KERNEL_MINOR_VERSION; | 498 | arg->minor = FUSE_KERNEL_MINOR_VERSION; |
497 | req->in.h.opcode = FUSE_INIT; | 499 | req->in.h.opcode = FUSE_INIT; |