Skip to content

Commit

Permalink
fs/9p: Always ask new inode in create
Browse files Browse the repository at this point in the history
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: Aneesh Kumar K.V <aneesh.kumar@linux.vnet.ibm.com>
Signed-off-by: Eric Van Hensbergen <ericvh@gmail.com>
  • Loading branch information
Aneesh Kumar K.V authored and Eric Van Hensbergen committed Jul 23, 2011
1 parent 4d63055 commit ed80fcf
Show file tree
Hide file tree
Showing 3 changed files with 61 additions and 18 deletions.
27 changes: 23 additions & 4 deletions fs/9p/v9fs.h
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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
22 changes: 17 additions & 5 deletions fs/9p/vfs_inode.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand All @@ -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))
Expand Down Expand Up @@ -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;
Expand All @@ -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;
Expand Down Expand Up @@ -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);
Expand Down
30 changes: 21 additions & 9 deletions fs/9p/vfs_inode_dotl.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand All @@ -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))
Expand Down Expand Up @@ -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;
Expand All @@ -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;
}
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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",
Expand Down Expand Up @@ -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",
Expand Down Expand Up @@ -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",
Expand Down

0 comments on commit ed80fcf

Please sign in to comment.