Skip to content

Commit

Permalink
fs/9p: Add inode hashing
Browse files Browse the repository at this point in the history
We didn't add the inode to inode hash in 9p. We need to do that
to get sync to work, otherwise __mark_inode_dirty will not
add the inode to super block's dirty list.

Signed-off-by: Aneesh Kumar K.V <aneesh.kumar@linux.vnet.ibm.com>
Signed-off-by: Venkateswararao Jujjuri <jvrao@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 Mar 15, 2011
1 parent 62d810b commit 5ffc0cb
Show file tree
Hide file tree
Showing 4 changed files with 124 additions and 70 deletions.
2 changes: 1 addition & 1 deletion fs/9p/acl.c
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,8 @@
#include <linux/posix_acl_xattr.h>
#include "xattr.h"
#include "acl.h"
#include "v9fs_vfs.h"
#include "v9fs.h"
#include "v9fs_vfs.h"

static struct posix_acl *__v9fs_get_acl(struct p9_fid *fid, char *name)
{
Expand Down
2 changes: 2 additions & 0 deletions fs/9p/v9fs_vfs.h
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,8 @@ void v9fs_destroy_inode(struct inode *inode);
#endif

struct inode *v9fs_get_inode(struct super_block *sb, int mode);
int v9fs_init_inode(struct v9fs_session_info *v9ses,
struct inode *inode, int mode);
void v9fs_evict_inode(struct inode *inode);
ino_t v9fs_qid2ino(struct p9_qid *qid);
void v9fs_stat2inode(struct p9_wstat *, struct inode *, struct super_block *);
Expand Down
121 changes: 75 additions & 46 deletions fs/9p/vfs_inode.c
Original file line number Diff line number Diff line change
Expand Up @@ -243,26 +243,10 @@ void v9fs_destroy_inode(struct inode *inode)
}
#endif

/**
* v9fs_get_inode - helper function to setup an inode
* @sb: superblock
* @mode: mode to setup inode with
*
*/

struct inode *v9fs_get_inode(struct super_block *sb, int mode)
int v9fs_init_inode(struct v9fs_session_info *v9ses,
struct inode *inode, int mode)
{
int err;
struct inode *inode;
struct v9fs_session_info *v9ses = sb->s_fs_info;

P9_DPRINTK(P9_DEBUG_VFS, "super block: %p mode: %o\n", sb, mode);

inode = new_inode(sb);
if (!inode) {
P9_EPRINTK(KERN_WARNING, "Problem allocating inode\n");
return ERR_PTR(-ENOMEM);
}
int err = 0;

inode_init_owner(inode, NULL, mode);
inode->i_blocks = 0;
Expand Down Expand Up @@ -306,7 +290,6 @@ struct inode *v9fs_get_inode(struct super_block *sb, int mode)
}

break;

case S_IFLNK:
if (!v9fs_proto_dotu(v9ses) && !v9fs_proto_dotl(v9ses)) {
P9_DPRINTK(P9_DEBUG_ERROR, "extended modes used with "
Expand Down Expand Up @@ -342,12 +325,37 @@ struct inode *v9fs_get_inode(struct super_block *sb, int mode)
err = -EINVAL;
goto error;
}
error:
return err;

return inode;
}

error:
iput(inode);
return ERR_PTR(err);
/**
* v9fs_get_inode - helper function to setup an inode
* @sb: superblock
* @mode: mode to setup inode with
*
*/

struct inode *v9fs_get_inode(struct super_block *sb, int mode)
{
int err;
struct inode *inode;
struct v9fs_session_info *v9ses = sb->s_fs_info;

P9_DPRINTK(P9_DEBUG_VFS, "super block: %p mode: %o\n", sb, mode);

inode = new_inode(sb);
if (!inode) {
P9_EPRINTK(KERN_WARNING, "Problem allocating inode\n");
return ERR_PTR(-ENOMEM);
}
err = v9fs_init_inode(v9ses, inode, mode);
if (err) {
iput(inode);
return ERR_PTR(err);
}
return inode;
}

/*
Expand Down Expand Up @@ -424,39 +432,60 @@ void v9fs_evict_inode(struct inode *inode)
}
}

struct inode *
v9fs_inode(struct v9fs_session_info *v9ses, struct p9_fid *fid,
struct super_block *sb)
static struct inode *v9fs_qid_iget(struct super_block *sb,
struct p9_qid *qid,
struct p9_wstat *st)
{
int err, umode;
struct inode *ret = NULL;
struct p9_wstat *st;

st = p9_client_stat(fid);
if (IS_ERR(st))
return ERR_CAST(st);
int retval, umode;
unsigned long i_ino;
struct inode *inode;
struct v9fs_session_info *v9ses = sb->s_fs_info;

i_ino = v9fs_qid2ino(qid);
inode = iget_locked(sb, i_ino);
if (!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.
*/
umode = p9mode2unixmode(v9ses, st->mode);
ret = v9fs_get_inode(sb, umode);
if (IS_ERR(ret)) {
err = PTR_ERR(ret);
retval = v9fs_init_inode(v9ses, inode, umode);
if (retval)
goto error;
}

v9fs_stat2inode(st, ret, sb);
ret->i_ino = v9fs_qid2ino(&st->qid);

v9fs_stat2inode(st, inode, sb);
#ifdef CONFIG_9P_FSCACHE
v9fs_vcookie_set_qid(ret, &st->qid);
v9fs_cache_inode_get_cookie(ret);
v9fs_cache_inode_get_cookie(inode);
#endif
p9stat_free(st);
kfree(st);
return ret;
unlock_new_inode(inode);
return inode;
error:
unlock_new_inode(inode);
iput(inode);
return ERR_PTR(retval);

}

struct inode *
v9fs_inode(struct v9fs_session_info *v9ses, struct p9_fid *fid,
struct super_block *sb)
{
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);
p9stat_free(st);
kfree(st);
return ERR_PTR(err);
return inode;
}

/**
Expand Down
69 changes: 46 additions & 23 deletions fs/9p/vfs_inode_dotl.c
Original file line number Diff line number Diff line change
Expand Up @@ -86,40 +86,63 @@ static struct dentry *v9fs_dentry_from_dir_inode(struct inode *inode)
return dentry;
}

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 retval;
unsigned long i_ino;
struct inode *inode;
struct v9fs_session_info *v9ses = sb->s_fs_info;

i_ino = v9fs_qid2ino(qid);
inode = iget_locked(sb, i_ino);
if (!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.
*/
retval = v9fs_init_inode(v9ses, inode, st->st_mode);
if (retval)
goto error;

v9fs_stat2inode_dotl(st, inode);
#ifdef CONFIG_9P_FSCACHE
v9fs_vcookie_set_qid(inode, &st->qid);
v9fs_cache_inode_get_cookie(inode);
#endif
retval = v9fs_get_acl(inode, fid);
if (retval)
goto error;

unlock_new_inode(inode);
return inode;
error:
unlock_new_inode(inode);
iput(inode);
return ERR_PTR(retval);

}

struct inode *
v9fs_inode_dotl(struct v9fs_session_info *v9ses, struct p9_fid *fid,
struct super_block *sb)
{
struct inode *ret = NULL;
int err;
struct p9_stat_dotl *st;
struct inode *inode = NULL;

st = p9_client_getattr_dotl(fid, P9_STATS_BASIC);
if (IS_ERR(st))
return ERR_CAST(st);

ret = v9fs_get_inode(sb, st->st_mode);
if (IS_ERR(ret)) {
err = PTR_ERR(ret);
goto error;
}

v9fs_stat2inode_dotl(st, ret);
ret->i_ino = v9fs_qid2ino(&st->qid);
#ifdef CONFIG_9P_FSCACHE
v9fs_vcookie_set_qid(ret, &st->qid);
v9fs_cache_inode_get_cookie(ret);
#endif
err = v9fs_get_acl(ret, fid);
if (err) {
iput(ret);
goto error;
}
kfree(st);
return ret;
error:
inode = v9fs_qid_iget_dotl(sb, &st->qid, fid, st);
kfree(st);
return ERR_PTR(err);
return inode;
}

/**
Expand Down

0 comments on commit 5ffc0cb

Please sign in to comment.