Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit ed80fcfa authored by Aneesh Kumar K.V's avatar Aneesh Kumar K.V Committed by Eric Van Hensbergen
Browse files

fs/9p: Always ask new inode in create



This make sure we don't end up reusing the unlinked inode object.
The ideal way is to use inode i_generation. But i_generation is
not available in userspace always.

Signed-off-by: default avatarAneesh Kumar K.V <aneesh.kumar@linux.vnet.ibm.com>
Signed-off-by: default avatarEric Van Hensbergen <ericvh@gmail.com>
parent 4d63055f
Loading
Loading
Loading
Loading
+23 −4
Original line number Diff line number Diff line
@@ -153,13 +153,13 @@ extern void v9fs_vfs_put_link(struct dentry *dentry, struct nameidata *nd,
			void *p);
extern struct inode *v9fs_inode_from_fid(struct v9fs_session_info *v9ses,
					 struct p9_fid *fid,
					 struct super_block *sb);
					 struct super_block *sb, int new);
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 struct inode *v9fs_inode_from_fid_dotl(struct v9fs_session_info *v9ses,
					      struct p9_fid *fid,
					      struct super_block *sb);
					      struct super_block *sb, int new);

/* other default globals */
#define V9FS_PORT	564
@@ -201,8 +201,27 @@ 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);
		return v9fs_inode_from_fid_dotl(v9ses, fid, sb, 0);
	else
		return v9fs_inode_from_fid(v9ses, fid, sb);
		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);
}

#endif
+17 −5
Original line number Diff line number Diff line
@@ -454,6 +454,11 @@ static int v9fs_test_inode(struct inode *inode, void *data)
	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);
@@ -465,15 +470,22 @@ static int v9fs_set_inode(struct inode *inode, void *data)

static struct inode *v9fs_qid_iget(struct super_block *sb,
				   struct p9_qid *qid,
				   struct p9_wstat *st)
				   struct p9_wstat *st,
				   int new)
{
	int retval, umode;
	unsigned long i_ino;
	struct inode *inode;
	struct v9fs_session_info *v9ses = sb->s_fs_info;
	int (*test)(struct inode *, void *);

	if (new)
		test = v9fs_test_new_inode;
	else
		test = v9fs_test_inode;

	i_ino = v9fs_qid2ino(qid);
	inode = iget5_locked(sb, i_ino, v9fs_test_inode, v9fs_set_inode, st);
	inode = iget5_locked(sb, i_ino, test, v9fs_set_inode, st);
	if (!inode)
		return ERR_PTR(-ENOMEM);
	if (!(inode->i_state & I_NEW))
@@ -504,7 +516,7 @@ 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)
		    struct super_block *sb, int new)
{
	struct p9_wstat *st;
	struct inode *inode = NULL;
@@ -513,7 +525,7 @@ v9fs_inode_from_fid(struct v9fs_session_info *v9ses, struct p9_fid *fid,
	if (IS_ERR(st))
		return ERR_CAST(st);

	inode = v9fs_qid_iget(sb, &st->qid, st);
	inode = v9fs_qid_iget(sb, &st->qid, st, new);
	p9stat_free(st);
	kfree(st);
	return inode;
@@ -615,7 +627,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);
	inode = v9fs_get_new_inode_from_fid(v9ses, fid, dir->i_sb);
	if (IS_ERR(inode)) {
		err = PTR_ERR(inode);
		P9_DPRINTK(P9_DEBUG_VFS, "inode creation failed %d\n", err);
+21 −9
Original line number Diff line number Diff line
@@ -108,6 +108,12 @@ static int v9fs_test_inode_dotl(struct inode *inode, void *data)
	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);
@@ -121,16 +127,22 @@ static int v9fs_set_inode_dotl(struct inode *inode, void *data)
static struct inode *v9fs_qid_iget_dotl(struct super_block *sb,
					struct p9_qid *qid,
					struct p9_fid *fid,
					struct p9_stat_dotl *st)
					struct p9_stat_dotl *st,
					int new)
{
	int retval;
	unsigned long i_ino;
	struct inode *inode;
	struct v9fs_session_info *v9ses = sb->s_fs_info;
	int (*test)(struct inode *, void *);

	if (new)
		test = v9fs_test_new_inode_dotl;
	else
		test = v9fs_test_inode_dotl;

	i_ino = v9fs_qid2ino(qid);
	inode = iget5_locked(sb, i_ino, v9fs_test_inode_dotl,
			     v9fs_set_inode_dotl, st);
	inode = iget5_locked(sb, i_ino, test, v9fs_set_inode_dotl, st);
	if (!inode)
		return ERR_PTR(-ENOMEM);
	if (!(inode->i_state & I_NEW))
@@ -164,7 +176,7 @@ 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)
			 struct super_block *sb, int new)
{
	struct p9_stat_dotl *st;
	struct inode *inode = NULL;
@@ -173,7 +185,7 @@ v9fs_inode_from_fid_dotl(struct v9fs_session_info *v9ses, struct p9_fid *fid,
	if (IS_ERR(st))
		return ERR_CAST(st);

	inode = v9fs_qid_iget_dotl(sb, &st->qid, fid, st);
	inode = v9fs_qid_iget_dotl(sb, &st->qid, fid, st, new);
	kfree(st);
	return inode;
}
@@ -263,7 +275,7 @@ v9fs_vfs_create_dotl(struct inode *dir, struct dentry *dentry, int omode,
		fid = NULL;
		goto error;
	}
	inode = v9fs_get_inode_from_fid(v9ses, fid, dir->i_sb);
	inode = v9fs_get_new_inode_from_fid(v9ses, fid, dir->i_sb);
	if (IS_ERR(inode)) {
		err = PTR_ERR(inode);
		P9_DPRINTK(P9_DEBUG_VFS, "inode creation failed %d\n", err);
@@ -383,7 +395,7 @@ static int v9fs_vfs_mkdir_dotl(struct inode *dir,
			goto error;
		}

		inode = v9fs_get_inode_from_fid(v9ses, fid, dir->i_sb);
		inode = v9fs_get_new_inode_from_fid(v9ses, fid, dir->i_sb);
		if (IS_ERR(inode)) {
			err = PTR_ERR(inode);
			P9_DPRINTK(P9_DEBUG_VFS, "inode creation failed %d\n",
@@ -636,7 +648,7 @@ v9fs_vfs_symlink_dotl(struct inode *dir, struct dentry *dentry,
		}

		/* instantiate inode and assign the unopened fid to dentry */
		inode = v9fs_get_inode_from_fid(v9ses, fid, dir->i_sb);
		inode = v9fs_get_new_inode_from_fid(v9ses, fid, dir->i_sb);
		if (IS_ERR(inode)) {
			err = PTR_ERR(inode);
			P9_DPRINTK(P9_DEBUG_VFS, "inode creation failed %d\n",
@@ -789,7 +801,7 @@ v9fs_vfs_mknod_dotl(struct inode *dir, struct dentry *dentry, int omode,
			goto error;
		}

		inode = v9fs_get_inode_from_fid(v9ses, fid, dir->i_sb);
		inode = v9fs_get_new_inode_from_fid(v9ses, fid, dir->i_sb);
		if (IS_ERR(inode)) {
			err = PTR_ERR(inode);
			P9_DPRINTK(P9_DEBUG_VFS, "inode creation failed %d\n",