Commit f69999b5 authored by Dominique Martinet's avatar Dominique Martinet
Browse files

Revert " fs/9p: mitigate inode collisions"



This reverts commit d05dcfdf.

This is a requirement to revert commit 724a0845 ("fs/9p: simplify
iget to remove unnecessary paths"), see that revert for details.

Fixes: 724a0845 ("fs/9p: simplify iget to remove unnecessary paths")
Reported-by: default avatarWill Deacon <will@kernel.org>
Link: https://lkml.kernel.org/r/20240923100508.GA32066@willie-the-truck


Cc: stable@vger.kernel.org # v6.9+
Message-ID: <20241024-revert_iget-v1-1-4cac63d25f72@codewreck.org>
Signed-off-by: default avatarDominique Martinet <asmadeus@codewreck.org>
parent 42f7652d
Loading
Loading
Loading
Loading
+5 −6
Original line number Diff line number Diff line
@@ -179,14 +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_fid_iget(struct super_block *sb, struct p9_fid *fid,
						bool 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_fid_iget_dotl(struct super_block *sb,
						struct p9_fid *fid, bool new);
					struct p9_fid *fid);

/* other default globals */
#define V9FS_PORT	564
@@ -225,12 +224,12 @@ static inline int v9fs_proto_dotl(struct v9fs_session_info *v9ses)
 */
static inline struct inode *
v9fs_get_inode_from_fid(struct v9fs_session_info *v9ses, struct p9_fid *fid,
			struct super_block *sb, bool new)
			struct super_block *sb)
{
	if (v9fs_proto_dotl(v9ses))
		return v9fs_fid_iget_dotl(sb, fid, new);
		return v9fs_fid_iget_dotl(sb, fid);
	else
		return v9fs_fid_iget(sb, fid, new);
		return v9fs_fid_iget(sb, fid);
}

#endif
+8 −29
Original line number Diff line number Diff line
@@ -366,8 +366,7 @@ void v9fs_evict_inode(struct inode *inode)
		clear_inode(inode);
}

struct inode *
v9fs_fid_iget(struct super_block *sb, struct p9_fid *fid, bool new)
struct inode *v9fs_fid_iget(struct super_block *sb, struct p9_fid *fid)
{
	dev_t rdev;
	int retval;
@@ -379,18 +378,8 @@ v9fs_fid_iget(struct super_block *sb, struct p9_fid *fid, bool new)
	inode = iget_locked(sb, QID2INO(&fid->qid));
	if (unlikely(!inode))
		return ERR_PTR(-ENOMEM);
	if (!(inode->i_state & I_NEW)) {
		if (!new) {
			goto done;
		} else {
			p9_debug(P9_DEBUG_VFS, "WARNING: Inode collision %ld\n",
						inode->i_ino);
			iput(inode);
			remove_inode_hash(inode);
			inode = iget_locked(sb, QID2INO(&fid->qid));
			WARN_ON(!(inode->i_state & I_NEW));
		}
	}
	if (!(inode->i_state & I_NEW))
		return inode;

	/*
	 * initialize the inode with the stat info
@@ -414,11 +403,11 @@ v9fs_fid_iget(struct super_block *sb, struct p9_fid *fid, bool new)
	v9fs_set_netfs_context(inode);
	v9fs_cache_inode_get_cookie(inode);
	unlock_new_inode(inode);
done:
	return inode;
error:
	iget_failed(inode);
	return ERR_PTR(retval);

}

/**
@@ -450,15 +439,8 @@ static int v9fs_at_to_dotl_flags(int flags)
 */
static void v9fs_dec_count(struct inode *inode)
{
	if (!S_ISDIR(inode->i_mode) || inode->i_nlink > 2) {
		if (inode->i_nlink) {
	if (!S_ISDIR(inode->i_mode) || inode->i_nlink > 2)
		drop_nlink(inode);
		} else {
			p9_debug(P9_DEBUG_VFS,
						"WARNING: unexpected i_nlink zero %d inode %ld\n",
						inode->i_nlink, inode->i_ino);
		}
	}
}

/**
@@ -509,9 +491,6 @@ static int v9fs_remove(struct inode *dir, struct dentry *dentry, int flags)
		} else
			v9fs_dec_count(inode);

		if (inode->i_nlink <= 0)	/* no more refs unhash it */
			remove_inode_hash(inode);

		v9fs_invalidate_inode_attr(inode);
		v9fs_invalidate_inode_attr(dir);

@@ -577,7 +556,7 @@ v9fs_create(struct v9fs_session_info *v9ses, struct inode *dir,
		/*
		 * instantiate inode and assign the unopened fid to the dentry
		 */
		inode = v9fs_get_inode_from_fid(v9ses, fid, dir->i_sb, true);
		inode = v9fs_get_inode_from_fid(v9ses, fid, dir->i_sb);
		if (IS_ERR(inode)) {
			err = PTR_ERR(inode);
			p9_debug(P9_DEBUG_VFS,
@@ -706,7 +685,7 @@ struct dentry *v9fs_vfs_lookup(struct inode *dir, struct dentry *dentry,
	else if (IS_ERR(fid))
		inode = ERR_CAST(fid);
	else
		inode = v9fs_get_inode_from_fid(v9ses, fid, dir->i_sb, false);
		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
+8 −20
Original line number Diff line number Diff line
@@ -52,10 +52,7 @@ static kgid_t v9fs_get_fsgid_for_create(struct inode *dir_inode)
	return current_fsgid();
}



struct inode *
v9fs_fid_iget_dotl(struct super_block *sb, struct p9_fid *fid, bool new)
struct inode *v9fs_fid_iget_dotl(struct super_block *sb, struct p9_fid *fid)
{
	int retval;
	struct inode *inode;
@@ -65,18 +62,8 @@ v9fs_fid_iget_dotl(struct super_block *sb, struct p9_fid *fid, bool new)
	inode = iget_locked(sb, QID2INO(&fid->qid));
	if (unlikely(!inode))
		return ERR_PTR(-ENOMEM);
	if (!(inode->i_state & I_NEW)) {
		if (!new) {
			goto done;
		} else { /* deal with race condition in inode number reuse */
			p9_debug(P9_DEBUG_ERROR, "WARNING: Inode collision %lx\n",
						inode->i_ino);
			iput(inode);
			remove_inode_hash(inode);
			inode = iget_locked(sb, QID2INO(&fid->qid));
			WARN_ON(!(inode->i_state & I_NEW));
		}
	}
	if (!(inode->i_state & I_NEW))
		return inode;

	/*
	 * initialize the inode with the stat info
@@ -103,11 +90,12 @@ v9fs_fid_iget_dotl(struct super_block *sb, struct p9_fid *fid, bool new)
		goto error;

	unlock_new_inode(inode);
done:

	return inode;
error:
	iget_failed(inode);
	return ERR_PTR(retval);

}

struct dotl_openflag_map {
@@ -259,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_fid_iget_dotl(dir->i_sb, fid, true);
	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);
@@ -352,7 +340,7 @@ static int v9fs_vfs_mkdir_dotl(struct mnt_idmap *idmap,
	}

	/* instantiate inode and assign the unopened fid to the dentry */
	inode = v9fs_fid_iget_dotl(dir->i_sb, fid, true);
	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",
@@ -788,7 +776,7 @@ v9fs_vfs_mknod_dotl(struct mnt_idmap *idmap, struct inode *dir,
			 err);
		goto error;
	}
	inode = v9fs_fid_iget_dotl(dir->i_sb, fid, true);
	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",
+1 −1
Original line number Diff line number Diff line
@@ -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_inode_from_fid(v9ses, fid, sb, true);
	inode = v9fs_get_inode_from_fid(v9ses, fid, sb);
	if (IS_ERR(inode)) {
		retval = PTR_ERR(inode);
		goto release_sb;