aboutsummaryrefslogtreecommitdiffstats
path: root/fs/fuse/inode.c
diff options
context:
space:
mode:
authorMiklos Szeredi <miklos@szeredi.hu>2006-04-26 04:49:16 -0400
committerMiklos Szeredi <miklos@szeredi.hu>2006-04-26 04:49:16 -0400
commit8aa09a50b5d9dbdf627f79e19d72d82994348089 (patch)
tree5b50a1b62c8b95223023053595c452b0641f5767 /fs/fuse/inode.c
parent6dbbcb120570d747b00783820ee02d1e1bcf63de (diff)
[fuse] fix race between checking and setting file->private_data
BKL does not protect against races if the task may sleep between checking and setting a value. So move checking of file->private_data near to setting it in fuse_fill_super(). Found by Al Viro. Signed-off-by: Miklos Szeredi <miklos@szeredi.hu>
Diffstat (limited to 'fs/fuse/inode.c')
-rw-r--r--fs/fuse/inode.c13
1 files changed, 8 insertions, 5 deletions
diff --git a/fs/fuse/inode.c b/fs/fuse/inode.c
index fd34037b0588..7627022446b2 100644
--- a/fs/fuse/inode.c
+++ b/fs/fuse/inode.c
@@ -500,11 +500,6 @@ static int fuse_fill_super(struct super_block *sb, void *data, int silent)
500 if (file->f_op != &fuse_dev_operations) 500 if (file->f_op != &fuse_dev_operations)
501 return -EINVAL; 501 return -EINVAL;
502 502
503 /* Setting file->private_data can't race with other mount()
504 instances, since BKL is held for ->get_sb() */
505 if (file->private_data)
506 return -EINVAL;
507
508 fc = new_conn(); 503 fc = new_conn();
509 if (!fc) 504 if (!fc)
510 return -ENOMEM; 505 return -ENOMEM;
@@ -540,6 +535,12 @@ static int fuse_fill_super(struct super_block *sb, void *data, int silent)
540 if (err) 535 if (err)
541 goto err_free_req; 536 goto err_free_req;
542 537
538 /* Setting file->private_data can't race with other mount()
539 instances, since BKL is held for ->get_sb() */
540 err = -EINVAL;
541 if (file->private_data)
542 goto err_kobject_del;
543
543 sb->s_root = root_dentry; 544 sb->s_root = root_dentry;
544 fc->mounted = 1; 545 fc->mounted = 1;
545 fc->connected = 1; 546 fc->connected = 1;
@@ -556,6 +557,8 @@ static int fuse_fill_super(struct super_block *sb, void *data, int silent)
556 557
557 return 0; 558 return 0;
558 559
560 err_kobject_del:
561 kobject_del(&fc->kobj);
559 err_free_req: 562 err_free_req:
560 fuse_request_free(init_req); 563 fuse_request_free(init_req);
561 err_put_root: 564 err_put_root: