summaryrefslogtreecommitdiffstats
path: root/fs/fuse/dir.c
diff options
context:
space:
mode:
authorAl Viro <viro@zeniv.linux.org.uk>2018-05-28 18:27:19 -0400
committerAl Viro <viro@zeniv.linux.org.uk>2018-08-01 23:18:53 -0400
commitc971e6a006175bd0f195c6346c4e8bc4089bec00 (patch)
tree7b5a8c5ec29f2e08fe09b8e7332f2288e247f495 /fs/fuse/dir.c
parentb0c6108ecf64fce3987f80c1610472a56d480d9a (diff)
kill d_instantiate_no_diralias()
The only user is fuse_create_new_entry(), and there it's used to mitigate the same mkdir/open-by-handle race as in nfs_mkdir(). The same solution applies - unhash the mkdir argument, then call d_splice_alias() and if that returns a reference to preexisting alias, dput() and report success. ->mkdir() argument left unhashed negative with the preexisting alias moved in the right place is just fine from the ->mkdir() callers point of view. Cc: Miklos Szeredi <miklos@szeredi.hu> Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
Diffstat (limited to 'fs/fuse/dir.c')
-rw-r--r--fs/fuse/dir.c15
1 files changed, 11 insertions, 4 deletions
diff --git a/fs/fuse/dir.c b/fs/fuse/dir.c
index 56231b31f806..4bbae6ac75c3 100644
--- a/fs/fuse/dir.c
+++ b/fs/fuse/dir.c
@@ -539,6 +539,7 @@ static int create_new_entry(struct fuse_conn *fc, struct fuse_args *args,
539{ 539{
540 struct fuse_entry_out outarg; 540 struct fuse_entry_out outarg;
541 struct inode *inode; 541 struct inode *inode;
542 struct dentry *d;
542 int err; 543 int err;
543 struct fuse_forget_link *forget; 544 struct fuse_forget_link *forget;
544 545
@@ -570,11 +571,17 @@ static int create_new_entry(struct fuse_conn *fc, struct fuse_args *args,
570 } 571 }
571 kfree(forget); 572 kfree(forget);
572 573
573 err = d_instantiate_no_diralias(entry, inode); 574 d_drop(entry);
574 if (err) 575 d = d_splice_alias(inode, entry);
575 return err; 576 if (IS_ERR(d))
577 return PTR_ERR(d);
576 578
577 fuse_change_entry_timeout(entry, &outarg); 579 if (d) {
580 fuse_change_entry_timeout(d, &outarg);
581 dput(d);
582 } else {
583 fuse_change_entry_timeout(entry, &outarg);
584 }
578 fuse_invalidate_attr(dir); 585 fuse_invalidate_attr(dir);
579 return 0; 586 return 0;
580 587