mirror of
				https://github.com/torvalds/linux.git
				synced 2025-10-31 16:48:26 +02:00 
			
		
		
		
	fs/9p: simplify iget to remove unnecessary paths
Remove the additional comparison operators and switch to simply lookup by inode number (aka qid.path). Signed-off-by: Eric Van Hensbergen <ericvh@kernel.org>
This commit is contained in:
		
							parent
							
								
									b91a26696e
								
							
						
					
					
						commit
						724a08450f
					
				
					 5 changed files with 45 additions and 180 deletions
				
			
		
							
								
								
									
										31
									
								
								fs/9p/v9fs.h
									
									
									
									
									
								
							
							
						
						
									
										31
									
								
								fs/9p/v9fs.h
									
									
									
									
									
								
							|  | @ -179,16 +179,13 @@ extern int v9fs_vfs_rename(struct mnt_idmap *idmap, | |||
| 			   struct inode *old_dir, struct dentry *old_dentry, | ||||
| 			   struct inode *new_dir, struct dentry *new_dentry, | ||||
| 			   unsigned int flags); | ||||
| extern struct inode *v9fs_inode_from_fid(struct v9fs_session_info *v9ses, | ||||
| 					 struct p9_fid *fid, | ||||
| 					 struct super_block *sb, int new); | ||||
| extern struct inode *v9fs_fid_iget(struct super_block *sb, struct p9_fid *fid); | ||||
| extern const struct inode_operations v9fs_dir_inode_operations_dotl; | ||||
| extern const struct inode_operations v9fs_file_inode_operations_dotl; | ||||
| extern const struct inode_operations v9fs_symlink_inode_operations_dotl; | ||||
| extern const struct netfs_request_ops v9fs_req_ops; | ||||
| extern struct inode *v9fs_inode_from_fid_dotl(struct v9fs_session_info *v9ses, | ||||
| 					      struct p9_fid *fid, | ||||
| 					      struct super_block *sb, int new); | ||||
| extern struct inode *v9fs_fid_iget_dotl(struct super_block *sb, | ||||
| 					struct p9_fid *fid); | ||||
| 
 | ||||
| /* other default globals */ | ||||
| #define V9FS_PORT	564 | ||||
|  | @ -230,27 +227,9 @@ v9fs_get_inode_from_fid(struct v9fs_session_info *v9ses, struct p9_fid *fid, | |||
| 			struct super_block *sb) | ||||
| { | ||||
| 	if (v9fs_proto_dotl(v9ses)) | ||||
| 		return v9fs_inode_from_fid_dotl(v9ses, fid, sb, 0); | ||||
| 		return v9fs_fid_iget_dotl(sb, fid); | ||||
| 	else | ||||
| 		return v9fs_inode_from_fid(v9ses, fid, sb, 0); | ||||
| } | ||||
| 
 | ||||
| /**
 | ||||
|  * v9fs_get_new_inode_from_fid - Helper routine to populate an inode by | ||||
|  * issuing a attribute request | ||||
|  * @v9ses: session information | ||||
|  * @fid: fid to issue attribute request for | ||||
|  * @sb: superblock on which to create inode | ||||
|  * | ||||
|  */ | ||||
| static inline struct inode * | ||||
| v9fs_get_new_inode_from_fid(struct v9fs_session_info *v9ses, struct p9_fid *fid, | ||||
| 			    struct super_block *sb) | ||||
| { | ||||
| 	if (v9fs_proto_dotl(v9ses)) | ||||
| 		return v9fs_inode_from_fid_dotl(v9ses, fid, sb, 1); | ||||
| 	else | ||||
| 		return v9fs_inode_from_fid(v9ses, fid, sb, 1); | ||||
| 		return v9fs_fid_iget(sb, fid); | ||||
| } | ||||
| 
 | ||||
| #endif | ||||
|  |  | |||
|  | @ -42,7 +42,7 @@ struct inode *v9fs_alloc_inode(struct super_block *sb); | |||
| void v9fs_free_inode(struct inode *inode); | ||||
| void v9fs_set_netfs_context(struct inode *inode); | ||||
| int v9fs_init_inode(struct v9fs_session_info *v9ses, | ||||
| 		    struct inode *inode, umode_t mode, dev_t rdev); | ||||
| 		    struct inode *inode, struct p9_qid *qid, umode_t mode, dev_t rdev); | ||||
| void v9fs_evict_inode(struct inode *inode); | ||||
| #if (BITS_PER_LONG == 32) | ||||
| #define QID2INO(q) ((ino_t) (((q)->path+2) ^ (((q)->path) >> 32))) | ||||
|  |  | |||
|  | @ -253,9 +253,12 @@ void v9fs_set_netfs_context(struct inode *inode) | |||
| } | ||||
| 
 | ||||
| int v9fs_init_inode(struct v9fs_session_info *v9ses, | ||||
| 		    struct inode *inode, umode_t mode, dev_t rdev) | ||||
| 		    struct inode *inode, struct p9_qid *qid, umode_t mode, dev_t rdev) | ||||
| { | ||||
| 	int err = 0; | ||||
| 	struct v9fs_inode *v9inode = V9FS_I(inode); | ||||
| 
 | ||||
| 	memcpy(&v9inode->qid, qid, sizeof(struct p9_qid)); | ||||
| 
 | ||||
| 	inode_init_owner(&nop_mnt_idmap, inode, NULL, mode); | ||||
| 	inode->i_blocks = 0; | ||||
|  | @ -354,80 +357,40 @@ void v9fs_evict_inode(struct inode *inode) | |||
| #endif | ||||
| } | ||||
| 
 | ||||
| static int v9fs_test_inode(struct inode *inode, void *data) | ||||
| { | ||||
| 	int umode; | ||||
| 	dev_t rdev; | ||||
| 	struct v9fs_inode *v9inode = V9FS_I(inode); | ||||
| 	struct p9_wstat *st = (struct p9_wstat *)data; | ||||
| 	struct v9fs_session_info *v9ses = v9fs_inode2v9ses(inode); | ||||
| 
 | ||||
| 	umode = p9mode2unixmode(v9ses, st, &rdev); | ||||
| 	/* don't match inode of different type */ | ||||
| 	if (inode_wrong_type(inode, umode)) | ||||
| 		return 0; | ||||
| 
 | ||||
| 	/* compare qid details */ | ||||
| 	if (memcmp(&v9inode->qid.version, | ||||
| 		   &st->qid.version, sizeof(v9inode->qid.version))) | ||||
| 		return 0; | ||||
| 
 | ||||
| 	if (v9inode->qid.type != st->qid.type) | ||||
| 		return 0; | ||||
| 
 | ||||
| 	if (v9inode->qid.path != st->qid.path) | ||||
| 		return 0; | ||||
| 	return 1; | ||||
| } | ||||
| 
 | ||||
| static int v9fs_test_new_inode(struct inode *inode, void *data) | ||||
| { | ||||
| 	return 0; | ||||
| } | ||||
| 
 | ||||
| static int v9fs_set_inode(struct inode *inode,  void *data) | ||||
| { | ||||
| 	struct v9fs_inode *v9inode = V9FS_I(inode); | ||||
| 	struct p9_wstat *st = (struct p9_wstat *)data; | ||||
| 
 | ||||
| 	memcpy(&v9inode->qid, &st->qid, sizeof(st->qid)); | ||||
| 	return 0; | ||||
| } | ||||
| 
 | ||||
| static struct inode *v9fs_qid_iget(struct super_block *sb, | ||||
| 				   struct p9_qid *qid, | ||||
| 				   struct p9_wstat *st, | ||||
| 				   int new) | ||||
| struct inode *v9fs_fid_iget(struct super_block *sb, struct p9_fid *fid) | ||||
| { | ||||
| 	dev_t rdev; | ||||
| 	int retval; | ||||
| 	umode_t umode; | ||||
| 	struct inode *inode; | ||||
| 	struct p9_wstat *st; | ||||
| 	struct v9fs_session_info *v9ses = sb->s_fs_info; | ||||
| 	int (*test)(struct inode *inode, void *data); | ||||
| 
 | ||||
| 	if (new) | ||||
| 		test = v9fs_test_new_inode; | ||||
| 	else | ||||
| 		test = v9fs_test_inode; | ||||
| 
 | ||||
| 	inode = iget5_locked(sb, QID2INO(qid), test, v9fs_set_inode, st); | ||||
| 	if (!inode) | ||||
| 	inode = iget_locked(sb, QID2INO(&fid->qid)); | ||||
| 	if (unlikely(!inode)) | ||||
| 		return ERR_PTR(-ENOMEM); | ||||
| 	if (!(inode->i_state & I_NEW)) | ||||
| 		return inode; | ||||
| 
 | ||||
| 	/*
 | ||||
| 	 * initialize the inode with the stat info | ||||
| 	 * FIXME!! we may need support for stale inodes | ||||
| 	 * later. | ||||
| 	 */ | ||||
| 	inode->i_ino = QID2INO(qid); | ||||
| 	st = p9_client_stat(fid); | ||||
| 	if (IS_ERR(st)) { | ||||
| 		retval = PTR_ERR(st); | ||||
| 		goto error; | ||||
| 	} | ||||
| 
 | ||||
| 	umode = p9mode2unixmode(v9ses, st, &rdev); | ||||
| 	retval = v9fs_init_inode(v9ses, inode, umode, rdev); | ||||
| 	retval = v9fs_init_inode(v9ses, inode, &fid->qid, umode, rdev); | ||||
| 	v9fs_stat2inode(st, inode, sb, 0); | ||||
| 	p9stat_free(st); | ||||
| 	kfree(st); | ||||
| 	if (retval) | ||||
| 		goto error; | ||||
| 
 | ||||
| 	v9fs_stat2inode(st, inode, sb, 0); | ||||
| 	v9fs_set_netfs_context(inode); | ||||
| 	v9fs_cache_inode_get_cookie(inode); | ||||
| 	unlock_new_inode(inode); | ||||
|  | @ -438,23 +401,6 @@ static struct inode *v9fs_qid_iget(struct super_block *sb, | |||
| 
 | ||||
| } | ||||
| 
 | ||||
| struct inode * | ||||
| v9fs_inode_from_fid(struct v9fs_session_info *v9ses, struct p9_fid *fid, | ||||
| 		    struct super_block *sb, int new) | ||||
| { | ||||
| 	struct p9_wstat *st; | ||||
| 	struct inode *inode = NULL; | ||||
| 
 | ||||
| 	st = p9_client_stat(fid); | ||||
| 	if (IS_ERR(st)) | ||||
| 		return ERR_CAST(st); | ||||
| 
 | ||||
| 	inode = v9fs_qid_iget(sb, &st->qid, st, new); | ||||
| 	p9stat_free(st); | ||||
| 	kfree(st); | ||||
| 	return inode; | ||||
| } | ||||
| 
 | ||||
| /**
 | ||||
|  * v9fs_at_to_dotl_flags- convert Linux specific AT flags to | ||||
|  * plan 9 AT flag. | ||||
|  | @ -601,7 +547,7 @@ v9fs_create(struct v9fs_session_info *v9ses, struct inode *dir, | |||
| 		/*
 | ||||
| 		 * instantiate inode and assign the unopened fid to the dentry | ||||
| 		 */ | ||||
| 		inode = v9fs_get_new_inode_from_fid(v9ses, fid, dir->i_sb); | ||||
| 		inode = v9fs_get_inode_from_fid(v9ses, fid, dir->i_sb); | ||||
| 		if (IS_ERR(inode)) { | ||||
| 			err = PTR_ERR(inode); | ||||
| 			p9_debug(P9_DEBUG_VFS, | ||||
|  | @ -729,10 +675,8 @@ struct dentry *v9fs_vfs_lookup(struct inode *dir, struct dentry *dentry, | |||
| 		inode = NULL; | ||||
| 	else if (IS_ERR(fid)) | ||||
| 		inode = ERR_CAST(fid); | ||||
| 	else if (v9ses->cache & (CACHE_META|CACHE_LOOSE)) | ||||
| 		inode = v9fs_get_inode_from_fid(v9ses, fid, dir->i_sb); | ||||
| 	else | ||||
| 		inode = v9fs_get_new_inode_from_fid(v9ses, fid, dir->i_sb); | ||||
| 		inode = v9fs_get_inode_from_fid(v9ses, fid, dir->i_sb); | ||||
| 	/*
 | ||||
| 	 * If we had a rename on the server and a parallel lookup | ||||
| 	 * for the new name, then make sure we instantiate with | ||||
|  |  | |||
|  | @ -52,76 +52,33 @@ static kgid_t v9fs_get_fsgid_for_create(struct inode *dir_inode) | |||
| 	return current_fsgid(); | ||||
| } | ||||
| 
 | ||||
| static int v9fs_test_inode_dotl(struct inode *inode, void *data) | ||||
| { | ||||
| 	struct v9fs_inode *v9inode = V9FS_I(inode); | ||||
| 	struct p9_stat_dotl *st = (struct p9_stat_dotl *)data; | ||||
| 
 | ||||
| 	/* don't match inode of different type */ | ||||
| 	if (inode_wrong_type(inode, st->st_mode)) | ||||
| 		return 0; | ||||
| 
 | ||||
| 	if (inode->i_generation != st->st_gen) | ||||
| 		return 0; | ||||
| 
 | ||||
| 	/* compare qid details */ | ||||
| 	if (memcmp(&v9inode->qid.version, | ||||
| 		   &st->qid.version, sizeof(v9inode->qid.version))) | ||||
| 		return 0; | ||||
| 
 | ||||
| 	if (v9inode->qid.type != st->qid.type) | ||||
| 		return 0; | ||||
| 
 | ||||
| 	if (v9inode->qid.path != st->qid.path) | ||||
| 		return 0; | ||||
| 	return 1; | ||||
| } | ||||
| 
 | ||||
| /* Always get a new inode */ | ||||
| static int v9fs_test_new_inode_dotl(struct inode *inode, void *data) | ||||
| { | ||||
| 	return 0; | ||||
| } | ||||
| 
 | ||||
| static int v9fs_set_inode_dotl(struct inode *inode,  void *data) | ||||
| { | ||||
| 	struct v9fs_inode *v9inode = V9FS_I(inode); | ||||
| 	struct p9_stat_dotl *st = (struct p9_stat_dotl *)data; | ||||
| 
 | ||||
| 	memcpy(&v9inode->qid, &st->qid, sizeof(st->qid)); | ||||
| 	inode->i_generation = st->st_gen; | ||||
| 	return 0; | ||||
| } | ||||
| 
 | ||||
| static struct inode *v9fs_qid_iget_dotl(struct super_block *sb, | ||||
| 					struct p9_qid *qid, | ||||
| 					struct p9_fid *fid, | ||||
| 					struct p9_stat_dotl *st, | ||||
| 					int new) | ||||
| struct inode *v9fs_fid_iget_dotl(struct super_block *sb, struct p9_fid *fid) | ||||
| { | ||||
| 	int retval; | ||||
| 	struct inode *inode; | ||||
| 	struct p9_stat_dotl *st; | ||||
| 	struct v9fs_session_info *v9ses = sb->s_fs_info; | ||||
| 	int (*test)(struct inode *inode, void *data); | ||||
| 
 | ||||
| 	if (new) | ||||
| 		test = v9fs_test_new_inode_dotl; | ||||
| 	else | ||||
| 		test = v9fs_test_inode_dotl; | ||||
| 
 | ||||
| 	inode = iget5_locked(sb, QID2INO(qid), test, v9fs_set_inode_dotl, st); | ||||
| 	if (!inode) | ||||
| 	inode = iget_locked(sb, QID2INO(&fid->qid)); | ||||
| 	if (unlikely(!inode)) | ||||
| 		return ERR_PTR(-ENOMEM); | ||||
| 	if (!(inode->i_state & I_NEW)) | ||||
| 		return inode; | ||||
| 
 | ||||
| 	/*
 | ||||
| 	 * initialize the inode with the stat info | ||||
| 	 * FIXME!! we may need support for stale inodes | ||||
| 	 * later. | ||||
| 	 */ | ||||
| 	inode->i_ino = QID2INO(qid); | ||||
| 	retval = v9fs_init_inode(v9ses, inode, | ||||
| 	st = p9_client_getattr_dotl(fid, P9_STATS_BASIC | P9_STATS_GEN); | ||||
| 	if (IS_ERR(st)) { | ||||
| 		retval = PTR_ERR(st); | ||||
| 		goto error; | ||||
| 	} | ||||
| 
 | ||||
| 	retval = v9fs_init_inode(v9ses, inode, &fid->qid, | ||||
| 				 st->st_mode, new_decode_dev(st->st_rdev)); | ||||
| 	kfree(st); | ||||
| 	if (retval) | ||||
| 		goto error; | ||||
| 
 | ||||
|  | @ -133,6 +90,7 @@ static struct inode *v9fs_qid_iget_dotl(struct super_block *sb, | |||
| 		goto error; | ||||
| 
 | ||||
| 	unlock_new_inode(inode); | ||||
| 
 | ||||
| 	return inode; | ||||
| error: | ||||
| 	iget_failed(inode); | ||||
|  | @ -140,22 +98,6 @@ static struct inode *v9fs_qid_iget_dotl(struct super_block *sb, | |||
| 
 | ||||
| } | ||||
| 
 | ||||
| struct inode * | ||||
| v9fs_inode_from_fid_dotl(struct v9fs_session_info *v9ses, struct p9_fid *fid, | ||||
| 			 struct super_block *sb, int new) | ||||
| { | ||||
| 	struct p9_stat_dotl *st; | ||||
| 	struct inode *inode = NULL; | ||||
| 
 | ||||
| 	st = p9_client_getattr_dotl(fid, P9_STATS_BASIC | P9_STATS_GEN); | ||||
| 	if (IS_ERR(st)) | ||||
| 		return ERR_CAST(st); | ||||
| 
 | ||||
| 	inode = v9fs_qid_iget_dotl(sb, &st->qid, fid, st, new); | ||||
| 	kfree(st); | ||||
| 	return inode; | ||||
| } | ||||
| 
 | ||||
| struct dotl_openflag_map { | ||||
| 	int open_flag; | ||||
| 	int dotl_flag; | ||||
|  | @ -305,7 +247,7 @@ v9fs_vfs_atomic_open_dotl(struct inode *dir, struct dentry *dentry, | |||
| 		p9_debug(P9_DEBUG_VFS, "p9_client_walk failed %d\n", err); | ||||
| 		goto out; | ||||
| 	} | ||||
| 	inode = v9fs_get_new_inode_from_fid(v9ses, fid, dir->i_sb); | ||||
| 	inode = v9fs_fid_iget_dotl(dir->i_sb, fid); | ||||
| 	if (IS_ERR(inode)) { | ||||
| 		err = PTR_ERR(inode); | ||||
| 		p9_debug(P9_DEBUG_VFS, "inode creation failed %d\n", err); | ||||
|  | @ -400,7 +342,7 @@ static int v9fs_vfs_mkdir_dotl(struct mnt_idmap *idmap, | |||
| 	} | ||||
| 
 | ||||
| 	/* instantiate inode and assign the unopened fid to the dentry */ | ||||
| 	inode = v9fs_get_new_inode_from_fid(v9ses, fid, dir->i_sb); | ||||
| 	inode = v9fs_fid_iget_dotl(dir->i_sb, fid); | ||||
| 	if (IS_ERR(inode)) { | ||||
| 		err = PTR_ERR(inode); | ||||
| 		p9_debug(P9_DEBUG_VFS, "inode creation failed %d\n", | ||||
|  | @ -838,7 +780,7 @@ v9fs_vfs_mknod_dotl(struct mnt_idmap *idmap, struct inode *dir, | |||
| 			 err); | ||||
| 		goto error; | ||||
| 	} | ||||
| 	inode = v9fs_get_new_inode_from_fid(v9ses, fid, dir->i_sb); | ||||
| 	inode = v9fs_fid_iget_dotl(dir->i_sb, fid); | ||||
| 	if (IS_ERR(inode)) { | ||||
| 		err = PTR_ERR(inode); | ||||
| 		p9_debug(P9_DEBUG_VFS, "inode creation failed %d\n", | ||||
|  |  | |||
|  | @ -139,7 +139,7 @@ static struct dentry *v9fs_mount(struct file_system_type *fs_type, int flags, | |||
| 	else | ||||
| 		sb->s_d_op = &v9fs_dentry_operations; | ||||
| 
 | ||||
| 	inode = v9fs_get_new_inode_from_fid(v9ses, fid, sb); | ||||
| 	inode = v9fs_get_inode_from_fid(v9ses, fid, sb); | ||||
| 	if (IS_ERR(inode)) { | ||||
| 		retval = PTR_ERR(inode); | ||||
| 		goto release_sb; | ||||
|  |  | |||
		Loading…
	
		Reference in a new issue
	
	 Eric Van Hensbergen
						Eric Van Hensbergen