fuse: switch to ->iterate_shared()
Switch dcache pre-seeding on readdir to d_alloc_parallel(); nothing else is needed. Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
This commit is contained in:
		
							parent
							
								
									f50752eaa0
								
							
						
					
					
						commit
						d9b3dbdcfd
					
				| @ -1162,7 +1162,6 @@ static int fuse_direntplus_link(struct file *file, | ||||
| 				struct fuse_direntplus *direntplus, | ||||
| 				u64 attr_version) | ||||
| { | ||||
| 	int err; | ||||
| 	struct fuse_entry_out *o = &direntplus->entry_out; | ||||
| 	struct fuse_dirent *dirent = &direntplus->dirent; | ||||
| 	struct dentry *parent = file->f_path.dentry; | ||||
| @ -1172,6 +1171,7 @@ static int fuse_direntplus_link(struct file *file, | ||||
| 	struct inode *dir = d_inode(parent); | ||||
| 	struct fuse_conn *fc; | ||||
| 	struct inode *inode; | ||||
| 	DECLARE_WAIT_QUEUE_HEAD_ONSTACK(wq); | ||||
| 
 | ||||
| 	if (!o->nodeid) { | ||||
| 		/*
 | ||||
| @ -1204,18 +1204,27 @@ static int fuse_direntplus_link(struct file *file, | ||||
| 
 | ||||
| 	name.hash = full_name_hash(name.name, name.len); | ||||
| 	dentry = d_lookup(parent, &name); | ||||
| 	if (dentry) { | ||||
| 	if (!dentry) { | ||||
| retry: | ||||
| 		dentry = d_alloc_parallel(parent, &name, &wq); | ||||
| 		if (IS_ERR(dentry)) | ||||
| 			return PTR_ERR(dentry); | ||||
| 	} | ||||
| 	if (!d_in_lookup(dentry)) { | ||||
| 		struct fuse_inode *fi; | ||||
| 		inode = d_inode(dentry); | ||||
| 		if (!inode) { | ||||
| 			d_drop(dentry); | ||||
| 		} else if (get_node_id(inode) != o->nodeid || | ||||
| 		if (!inode || | ||||
| 		    get_node_id(inode) != o->nodeid || | ||||
| 		    ((o->attr.mode ^ inode->i_mode) & S_IFMT)) { | ||||
| 			d_invalidate(dentry); | ||||
| 		} else if (is_bad_inode(inode)) { | ||||
| 			err = -EIO; | ||||
| 			goto out; | ||||
| 		} else { | ||||
| 			struct fuse_inode *fi; | ||||
| 			dput(dentry); | ||||
| 			goto retry; | ||||
| 		} | ||||
| 		if (is_bad_inode(inode)) { | ||||
| 			dput(dentry); | ||||
| 			return -EIO; | ||||
| 		} | ||||
| 
 | ||||
| 		fi = get_fuse_inode(inode); | ||||
| 		spin_lock(&fc->lock); | ||||
| 		fi->nlookup++; | ||||
| @ -1224,45 +1233,32 @@ static int fuse_direntplus_link(struct file *file, | ||||
| 		fuse_change_attributes(inode, &o->attr, | ||||
| 				       entry_attr_timeout(o), | ||||
| 				       attr_version); | ||||
| 
 | ||||
| 		/*
 | ||||
| 			 * The other branch to 'found' comes via fuse_iget() | ||||
| 		 * The other branch comes via fuse_iget() | ||||
| 		 * which bumps nlookup inside | ||||
| 		 */ | ||||
| 			goto found; | ||||
| 		} | ||||
| 		dput(dentry); | ||||
| 	} | ||||
| 
 | ||||
| 	dentry = d_alloc(parent, &name); | ||||
| 	err = -ENOMEM; | ||||
| 	if (!dentry) | ||||
| 		goto out; | ||||
| 
 | ||||
| 	} else { | ||||
| 		inode = fuse_iget(dir->i_sb, o->nodeid, o->generation, | ||||
| 			  &o->attr, entry_attr_timeout(o), attr_version); | ||||
| 				  &o->attr, entry_attr_timeout(o), | ||||
| 				  attr_version); | ||||
| 		if (!inode) | ||||
| 		goto out; | ||||
| 			inode = ERR_PTR(-ENOMEM); | ||||
| 
 | ||||
| 		alias = d_splice_alias(inode, dentry); | ||||
| 	err = PTR_ERR(alias); | ||||
| 	if (IS_ERR(alias)) | ||||
| 		goto out; | ||||
| 
 | ||||
| 		d_lookup_done(dentry); | ||||
| 		if (alias) { | ||||
| 			dput(dentry); | ||||
| 			dentry = alias; | ||||
| 		} | ||||
| 
 | ||||
| found: | ||||
| 		if (IS_ERR(dentry)) | ||||
| 			return PTR_ERR(dentry); | ||||
| 	} | ||||
| 	if (fc->readdirplus_auto) | ||||
| 		set_bit(FUSE_I_INIT_RDPLUS, &get_fuse_inode(inode)->state); | ||||
| 	fuse_change_entry_timeout(dentry, o); | ||||
| 
 | ||||
| 	err = 0; | ||||
| out: | ||||
| 	dput(dentry); | ||||
| 	return err; | ||||
| 	return 0; | ||||
| } | ||||
| 
 | ||||
| static int parse_dirplusfile(char *buf, size_t nbytes, struct file *file, | ||||
| @ -1892,7 +1888,7 @@ static const struct inode_operations fuse_dir_inode_operations = { | ||||
| static const struct file_operations fuse_dir_operations = { | ||||
| 	.llseek		= generic_file_llseek, | ||||
| 	.read		= generic_read_dir, | ||||
| 	.iterate	= fuse_readdir, | ||||
| 	.iterate_shared	= fuse_readdir, | ||||
| 	.open		= fuse_dir_open, | ||||
| 	.release	= fuse_dir_release, | ||||
| 	.fsync		= fuse_dir_fsync, | ||||
|  | ||||
		Loading…
	
		Reference in New Issue
	
	Block a user