aboutsummaryrefslogtreecommitdiffstats
path: root/fs/fuse/inode.c
diff options
context:
space:
mode:
authorMiklos Szeredi <miklos@szeredi.hu>2006-01-17 01:14:52 -0500
committerLinus Torvalds <torvalds@g5.osdl.org>2006-01-17 02:15:31 -0500
commit095da6cbb6a1c54c19b11190218eb0fbac666b6d (patch)
tree29ba46cea17454fe1888182f6722aee64e1a7ef5 /fs/fuse/inode.c
parentbacac382fbf53f717ca7f83558e45cce44e67df9 (diff)
[PATCH] fuse: fix bitfield race
Fix race in setting bitfields of fuse_conn. Spotted by Andrew Morton. The two fields ->connected and ->mounted were always changed with the fuse_lock held. But other bitfields in the same structure were changed without the lock. In theory this could lead to losing the assignment of even the ones under lock. The chosen solution is to change these two fields to be a full unsigned type. The other bitfields aren't "important" enough to warrant the extra complexity of full locking or changing them to bitops. For all bitfields document why they are safe wrt. concurrent assignments. Also make the initialization of the 'num_waiting' atomic counter explicit. Signed-off-by: Miklos Szeredi <miklos@szeredi.hu> Signed-off-by: Andrew Morton <akpm@osdl.org> Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Diffstat (limited to 'fs/fuse/inode.c')
-rw-r--r--fs/fuse/inode.c2
1 files changed, 2 insertions, 0 deletions
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;