lkml.org 
[lkml]   [2011]   [Sep]   [28]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    Date
    From
    Subject[086/244] fs/9p: Always ask new inode in create
    3.0-stable review patch.  If anyone has any objections, please let us know.

    ------------------

    From: "Aneesh Kumar K.V" <aneesh.kumar@linux.vnet.ibm.com>

    commit ed80fcfac2565fa866d93ba14f0e75de17a8223e upstream.

    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>
    Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>

    ---
    fs/9p/v9fs.h | 27 +++++++++++++++++++++++----
    fs/9p/vfs_inode.c | 22 +++++++++++++++++-----
    fs/9p/vfs_inode_dotl.c | 30 +++++++++++++++++++++---------
    3 files changed, 61 insertions(+), 18 deletions(-)

    --- a/fs/9p/v9fs.h
    +++ b/fs/9p/v9fs.h
    @@ -153,13 +153,13 @@ extern void v9fs_vfs_put_link(struct den
    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_sess
    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
    --- a/fs/9p/vfs_inode.c
    +++ b/fs/9p/vfs_inode.c
    @@ -454,6 +454,11 @@ static int v9fs_test_inode(struct inode
    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 *

    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 @@ error:

    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_
    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 *v9
    }

    /* 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);
    --- a/fs/9p/vfs_inode_dotl.c
    +++ b/fs/9p/vfs_inode_dotl.c
    @@ -108,6 +108,12 @@ static int v9fs_test_inode_dotl(struct i
    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 in
    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 @@ error:

    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_ses
    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,
    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 in
    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,
    }

    /* 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, s
    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",



    \
     
     \ /
      Last update: 2011-09-29 00:47    [W:4.088 / U:0.104 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site