[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>

+8 -5
+8 -5
fs/fuse/inode.c
··· 500 500 if (file->f_op != &fuse_dev_operations) 501 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 503 fc = new_conn(); 509 504 if (!fc) 510 505 return -ENOMEM; ··· 535 540 if (err) 536 541 goto err_free_req; 537 542 543 + /* Setting file->private_data can't race with other mount() 544 + instances, since BKL is held for ->get_sb() */ 545 + err = -EINVAL; 546 + if (file->private_data) 547 + goto err_kobject_del; 548 + 538 549 sb->s_root = root_dentry; 539 550 fc->mounted = 1; 540 551 fc->connected = 1; ··· 557 556 558 557 return 0; 559 558 559 + err_kobject_del: 560 + kobject_del(&fc->kobj); 560 561 err_free_req: 561 562 fuse_request_free(init_req); 562 563 err_put_root: