mirror of
https://github.com/torvalds/linux
synced 2024-10-15 07:47:34 +00:00
fs/9p: simplify iget to remove unnecessary paths
Remove the additional comparison operators and switch to simply lookup by inode number (aka qid.path). Signed-off-by: Eric Van Hensbergen <ericvh@kernel.org>
This commit is contained in:
parent
b91a26696e
commit
724a08450f
31
fs/9p/v9fs.h
31
fs/9p/v9fs.h
|
@ -179,16 +179,13 @@ extern int v9fs_vfs_rename(struct mnt_idmap *idmap,
|
||||||
struct inode *old_dir, struct dentry *old_dentry,
|
struct inode *old_dir, struct dentry *old_dentry,
|
||||||
struct inode *new_dir, struct dentry *new_dentry,
|
struct inode *new_dir, struct dentry *new_dentry,
|
||||||
unsigned int flags);
|
unsigned int flags);
|
||||||
extern struct inode *v9fs_inode_from_fid(struct v9fs_session_info *v9ses,
|
extern struct inode *v9fs_fid_iget(struct super_block *sb, struct p9_fid *fid);
|
||||||
struct p9_fid *fid,
|
|
||||||
struct super_block *sb, int new);
|
|
||||||
extern const struct inode_operations v9fs_dir_inode_operations_dotl;
|
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_file_inode_operations_dotl;
|
||||||
extern const struct inode_operations v9fs_symlink_inode_operations_dotl;
|
extern const struct inode_operations v9fs_symlink_inode_operations_dotl;
|
||||||
extern const struct netfs_request_ops v9fs_req_ops;
|
extern const struct netfs_request_ops v9fs_req_ops;
|
||||||
extern struct inode *v9fs_inode_from_fid_dotl(struct v9fs_session_info *v9ses,
|
extern struct inode *v9fs_fid_iget_dotl(struct super_block *sb,
|
||||||
struct p9_fid *fid,
|
struct p9_fid *fid);
|
||||||
struct super_block *sb, int new);
|
|
||||||
|
|
||||||
/* other default globals */
|
/* other default globals */
|
||||||
#define V9FS_PORT 564
|
#define V9FS_PORT 564
|
||||||
|
@ -230,27 +227,9 @@ v9fs_get_inode_from_fid(struct v9fs_session_info *v9ses, struct p9_fid *fid,
|
||||||
struct super_block *sb)
|
struct super_block *sb)
|
||||||
{
|
{
|
||||||
if (v9fs_proto_dotl(v9ses))
|
if (v9fs_proto_dotl(v9ses))
|
||||||
return v9fs_inode_from_fid_dotl(v9ses, fid, sb, 0);
|
return v9fs_fid_iget_dotl(sb, fid);
|
||||||
else
|
else
|
||||||
return v9fs_inode_from_fid(v9ses, fid, sb, 0);
|
return v9fs_fid_iget(sb, fid);
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 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
|
#endif
|
||||||
|
|
|
@ -42,7 +42,7 @@ struct inode *v9fs_alloc_inode(struct super_block *sb);
|
||||||
void v9fs_free_inode(struct inode *inode);
|
void v9fs_free_inode(struct inode *inode);
|
||||||
void v9fs_set_netfs_context(struct inode *inode);
|
void v9fs_set_netfs_context(struct inode *inode);
|
||||||
int v9fs_init_inode(struct v9fs_session_info *v9ses,
|
int v9fs_init_inode(struct v9fs_session_info *v9ses,
|
||||||
struct inode *inode, umode_t mode, dev_t rdev);
|
struct inode *inode, struct p9_qid *qid, umode_t mode, dev_t rdev);
|
||||||
void v9fs_evict_inode(struct inode *inode);
|
void v9fs_evict_inode(struct inode *inode);
|
||||||
#if (BITS_PER_LONG == 32)
|
#if (BITS_PER_LONG == 32)
|
||||||
#define QID2INO(q) ((ino_t) (((q)->path+2) ^ (((q)->path) >> 32)))
|
#define QID2INO(q) ((ino_t) (((q)->path+2) ^ (((q)->path) >> 32)))
|
||||||
|
|
|
@ -253,9 +253,12 @@ void v9fs_set_netfs_context(struct inode *inode)
|
||||||
}
|
}
|
||||||
|
|
||||||
int v9fs_init_inode(struct v9fs_session_info *v9ses,
|
int v9fs_init_inode(struct v9fs_session_info *v9ses,
|
||||||
struct inode *inode, umode_t mode, dev_t rdev)
|
struct inode *inode, struct p9_qid *qid, umode_t mode, dev_t rdev)
|
||||||
{
|
{
|
||||||
int err = 0;
|
int err = 0;
|
||||||
|
struct v9fs_inode *v9inode = V9FS_I(inode);
|
||||||
|
|
||||||
|
memcpy(&v9inode->qid, qid, sizeof(struct p9_qid));
|
||||||
|
|
||||||
inode_init_owner(&nop_mnt_idmap, inode, NULL, mode);
|
inode_init_owner(&nop_mnt_idmap, inode, NULL, mode);
|
||||||
inode->i_blocks = 0;
|
inode->i_blocks = 0;
|
||||||
|
@ -354,80 +357,40 @@ void v9fs_evict_inode(struct inode *inode)
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
static int v9fs_test_inode(struct inode *inode, void *data)
|
struct inode *v9fs_fid_iget(struct super_block *sb, struct p9_fid *fid)
|
||||||
{
|
|
||||||
int umode;
|
|
||||||
dev_t rdev;
|
|
||||||
struct v9fs_inode *v9inode = V9FS_I(inode);
|
|
||||||
struct p9_wstat *st = (struct p9_wstat *)data;
|
|
||||||
struct v9fs_session_info *v9ses = v9fs_inode2v9ses(inode);
|
|
||||||
|
|
||||||
umode = p9mode2unixmode(v9ses, st, &rdev);
|
|
||||||
/* don't match inode of different type */
|
|
||||||
if (inode_wrong_type(inode, umode))
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
/* compare qid details */
|
|
||||||
if (memcmp(&v9inode->qid.version,
|
|
||||||
&st->qid.version, sizeof(v9inode->qid.version)))
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
if (v9inode->qid.type != st->qid.type)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
if (v9inode->qid.path != st->qid.path)
|
|
||||||
return 0;
|
|
||||||
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);
|
|
||||||
struct p9_wstat *st = (struct p9_wstat *)data;
|
|
||||||
|
|
||||||
memcpy(&v9inode->qid, &st->qid, sizeof(st->qid));
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static struct inode *v9fs_qid_iget(struct super_block *sb,
|
|
||||||
struct p9_qid *qid,
|
|
||||||
struct p9_wstat *st,
|
|
||||||
int new)
|
|
||||||
{
|
{
|
||||||
dev_t rdev;
|
dev_t rdev;
|
||||||
int retval;
|
int retval;
|
||||||
umode_t umode;
|
umode_t umode;
|
||||||
struct inode *inode;
|
struct inode *inode;
|
||||||
|
struct p9_wstat *st;
|
||||||
struct v9fs_session_info *v9ses = sb->s_fs_info;
|
struct v9fs_session_info *v9ses = sb->s_fs_info;
|
||||||
int (*test)(struct inode *inode, void *data);
|
|
||||||
|
|
||||||
if (new)
|
inode = iget_locked(sb, QID2INO(&fid->qid));
|
||||||
test = v9fs_test_new_inode;
|
if (unlikely(!inode))
|
||||||
else
|
|
||||||
test = v9fs_test_inode;
|
|
||||||
|
|
||||||
inode = iget5_locked(sb, QID2INO(qid), test, v9fs_set_inode, st);
|
|
||||||
if (!inode)
|
|
||||||
return ERR_PTR(-ENOMEM);
|
return ERR_PTR(-ENOMEM);
|
||||||
if (!(inode->i_state & I_NEW))
|
if (!(inode->i_state & I_NEW))
|
||||||
return inode;
|
return inode;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* initialize the inode with the stat info
|
* initialize the inode with the stat info
|
||||||
* FIXME!! we may need support for stale inodes
|
* FIXME!! we may need support for stale inodes
|
||||||
* later.
|
* later.
|
||||||
*/
|
*/
|
||||||
inode->i_ino = QID2INO(qid);
|
st = p9_client_stat(fid);
|
||||||
|
if (IS_ERR(st)) {
|
||||||
|
retval = PTR_ERR(st);
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
|
||||||
umode = p9mode2unixmode(v9ses, st, &rdev);
|
umode = p9mode2unixmode(v9ses, st, &rdev);
|
||||||
retval = v9fs_init_inode(v9ses, inode, umode, rdev);
|
retval = v9fs_init_inode(v9ses, inode, &fid->qid, umode, rdev);
|
||||||
|
v9fs_stat2inode(st, inode, sb, 0);
|
||||||
|
p9stat_free(st);
|
||||||
|
kfree(st);
|
||||||
if (retval)
|
if (retval)
|
||||||
goto error;
|
goto error;
|
||||||
|
|
||||||
v9fs_stat2inode(st, inode, sb, 0);
|
|
||||||
v9fs_set_netfs_context(inode);
|
v9fs_set_netfs_context(inode);
|
||||||
v9fs_cache_inode_get_cookie(inode);
|
v9fs_cache_inode_get_cookie(inode);
|
||||||
unlock_new_inode(inode);
|
unlock_new_inode(inode);
|
||||||
|
@ -438,23 +401,6 @@ 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, int new)
|
|
||||||
{
|
|
||||||
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, new);
|
|
||||||
p9stat_free(st);
|
|
||||||
kfree(st);
|
|
||||||
return inode;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* v9fs_at_to_dotl_flags- convert Linux specific AT flags to
|
* v9fs_at_to_dotl_flags- convert Linux specific AT flags to
|
||||||
* plan 9 AT flag.
|
* plan 9 AT flag.
|
||||||
|
@ -601,7 +547,7 @@ v9fs_create(struct v9fs_session_info *v9ses, struct inode *dir,
|
||||||
/*
|
/*
|
||||||
* instantiate inode and assign the unopened fid to the dentry
|
* instantiate inode and assign the unopened fid to the dentry
|
||||||
*/
|
*/
|
||||||
inode = v9fs_get_new_inode_from_fid(v9ses, fid, dir->i_sb);
|
inode = v9fs_get_inode_from_fid(v9ses, fid, dir->i_sb);
|
||||||
if (IS_ERR(inode)) {
|
if (IS_ERR(inode)) {
|
||||||
err = PTR_ERR(inode);
|
err = PTR_ERR(inode);
|
||||||
p9_debug(P9_DEBUG_VFS,
|
p9_debug(P9_DEBUG_VFS,
|
||||||
|
@ -729,10 +675,8 @@ struct dentry *v9fs_vfs_lookup(struct inode *dir, struct dentry *dentry,
|
||||||
inode = NULL;
|
inode = NULL;
|
||||||
else if (IS_ERR(fid))
|
else if (IS_ERR(fid))
|
||||||
inode = ERR_CAST(fid);
|
inode = ERR_CAST(fid);
|
||||||
else if (v9ses->cache & (CACHE_META|CACHE_LOOSE))
|
|
||||||
inode = v9fs_get_inode_from_fid(v9ses, fid, dir->i_sb);
|
|
||||||
else
|
else
|
||||||
inode = v9fs_get_new_inode_from_fid(v9ses, fid, dir->i_sb);
|
inode = v9fs_get_inode_from_fid(v9ses, fid, dir->i_sb);
|
||||||
/*
|
/*
|
||||||
* If we had a rename on the server and a parallel lookup
|
* If we had a rename on the server and a parallel lookup
|
||||||
* for the new name, then make sure we instantiate with
|
* for the new name, then make sure we instantiate with
|
||||||
|
|
|
@ -52,76 +52,33 @@ static kgid_t v9fs_get_fsgid_for_create(struct inode *dir_inode)
|
||||||
return current_fsgid();
|
return current_fsgid();
|
||||||
}
|
}
|
||||||
|
|
||||||
static int v9fs_test_inode_dotl(struct inode *inode, void *data)
|
struct inode *v9fs_fid_iget_dotl(struct super_block *sb, struct p9_fid *fid)
|
||||||
{
|
|
||||||
struct v9fs_inode *v9inode = V9FS_I(inode);
|
|
||||||
struct p9_stat_dotl *st = (struct p9_stat_dotl *)data;
|
|
||||||
|
|
||||||
/* don't match inode of different type */
|
|
||||||
if (inode_wrong_type(inode, st->st_mode))
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
if (inode->i_generation != st->st_gen)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
/* compare qid details */
|
|
||||||
if (memcmp(&v9inode->qid.version,
|
|
||||||
&st->qid.version, sizeof(v9inode->qid.version)))
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
if (v9inode->qid.type != st->qid.type)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
if (v9inode->qid.path != st->qid.path)
|
|
||||||
return 0;
|
|
||||||
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);
|
|
||||||
struct p9_stat_dotl *st = (struct p9_stat_dotl *)data;
|
|
||||||
|
|
||||||
memcpy(&v9inode->qid, &st->qid, sizeof(st->qid));
|
|
||||||
inode->i_generation = st->st_gen;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
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 new)
|
|
||||||
{
|
{
|
||||||
int retval;
|
int retval;
|
||||||
struct inode *inode;
|
struct inode *inode;
|
||||||
|
struct p9_stat_dotl *st;
|
||||||
struct v9fs_session_info *v9ses = sb->s_fs_info;
|
struct v9fs_session_info *v9ses = sb->s_fs_info;
|
||||||
int (*test)(struct inode *inode, void *data);
|
|
||||||
|
|
||||||
if (new)
|
inode = iget_locked(sb, QID2INO(&fid->qid));
|
||||||
test = v9fs_test_new_inode_dotl;
|
if (unlikely(!inode))
|
||||||
else
|
|
||||||
test = v9fs_test_inode_dotl;
|
|
||||||
|
|
||||||
inode = iget5_locked(sb, QID2INO(qid), test, v9fs_set_inode_dotl, st);
|
|
||||||
if (!inode)
|
|
||||||
return ERR_PTR(-ENOMEM);
|
return ERR_PTR(-ENOMEM);
|
||||||
if (!(inode->i_state & I_NEW))
|
if (!(inode->i_state & I_NEW))
|
||||||
return inode;
|
return inode;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* initialize the inode with the stat info
|
* initialize the inode with the stat info
|
||||||
* FIXME!! we may need support for stale inodes
|
* FIXME!! we may need support for stale inodes
|
||||||
* later.
|
* later.
|
||||||
*/
|
*/
|
||||||
inode->i_ino = QID2INO(qid);
|
st = p9_client_getattr_dotl(fid, P9_STATS_BASIC | P9_STATS_GEN);
|
||||||
retval = v9fs_init_inode(v9ses, inode,
|
if (IS_ERR(st)) {
|
||||||
|
retval = PTR_ERR(st);
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
|
||||||
|
retval = v9fs_init_inode(v9ses, inode, &fid->qid,
|
||||||
st->st_mode, new_decode_dev(st->st_rdev));
|
st->st_mode, new_decode_dev(st->st_rdev));
|
||||||
|
kfree(st);
|
||||||
if (retval)
|
if (retval)
|
||||||
goto error;
|
goto error;
|
||||||
|
|
||||||
|
@ -133,6 +90,7 @@ static struct inode *v9fs_qid_iget_dotl(struct super_block *sb,
|
||||||
goto error;
|
goto error;
|
||||||
|
|
||||||
unlock_new_inode(inode);
|
unlock_new_inode(inode);
|
||||||
|
|
||||||
return inode;
|
return inode;
|
||||||
error:
|
error:
|
||||||
iget_failed(inode);
|
iget_failed(inode);
|
||||||
|
@ -140,22 +98,6 @@ 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, int new)
|
|
||||||
{
|
|
||||||
struct p9_stat_dotl *st;
|
|
||||||
struct inode *inode = NULL;
|
|
||||||
|
|
||||||
st = p9_client_getattr_dotl(fid, P9_STATS_BASIC | P9_STATS_GEN);
|
|
||||||
if (IS_ERR(st))
|
|
||||||
return ERR_CAST(st);
|
|
||||||
|
|
||||||
inode = v9fs_qid_iget_dotl(sb, &st->qid, fid, st, new);
|
|
||||||
kfree(st);
|
|
||||||
return inode;
|
|
||||||
}
|
|
||||||
|
|
||||||
struct dotl_openflag_map {
|
struct dotl_openflag_map {
|
||||||
int open_flag;
|
int open_flag;
|
||||||
int dotl_flag;
|
int dotl_flag;
|
||||||
|
@ -305,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);
|
p9_debug(P9_DEBUG_VFS, "p9_client_walk failed %d\n", err);
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
inode = v9fs_get_new_inode_from_fid(v9ses, fid, dir->i_sb);
|
inode = v9fs_fid_iget_dotl(dir->i_sb, fid);
|
||||||
if (IS_ERR(inode)) {
|
if (IS_ERR(inode)) {
|
||||||
err = PTR_ERR(inode);
|
err = PTR_ERR(inode);
|
||||||
p9_debug(P9_DEBUG_VFS, "inode creation failed %d\n", err);
|
p9_debug(P9_DEBUG_VFS, "inode creation failed %d\n", err);
|
||||||
|
@ -400,7 +342,7 @@ static int v9fs_vfs_mkdir_dotl(struct mnt_idmap *idmap,
|
||||||
}
|
}
|
||||||
|
|
||||||
/* instantiate inode and assign the unopened fid to the dentry */
|
/* instantiate inode and assign the unopened fid to the dentry */
|
||||||
inode = v9fs_get_new_inode_from_fid(v9ses, fid, dir->i_sb);
|
inode = v9fs_fid_iget_dotl(dir->i_sb, fid);
|
||||||
if (IS_ERR(inode)) {
|
if (IS_ERR(inode)) {
|
||||||
err = PTR_ERR(inode);
|
err = PTR_ERR(inode);
|
||||||
p9_debug(P9_DEBUG_VFS, "inode creation failed %d\n",
|
p9_debug(P9_DEBUG_VFS, "inode creation failed %d\n",
|
||||||
|
@ -838,7 +780,7 @@ v9fs_vfs_mknod_dotl(struct mnt_idmap *idmap, struct inode *dir,
|
||||||
err);
|
err);
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
inode = v9fs_get_new_inode_from_fid(v9ses, fid, dir->i_sb);
|
inode = v9fs_fid_iget_dotl(dir->i_sb, fid);
|
||||||
if (IS_ERR(inode)) {
|
if (IS_ERR(inode)) {
|
||||||
err = PTR_ERR(inode);
|
err = PTR_ERR(inode);
|
||||||
p9_debug(P9_DEBUG_VFS, "inode creation failed %d\n",
|
p9_debug(P9_DEBUG_VFS, "inode creation failed %d\n",
|
||||||
|
|
|
@ -139,7 +139,7 @@ static struct dentry *v9fs_mount(struct file_system_type *fs_type, int flags,
|
||||||
else
|
else
|
||||||
sb->s_d_op = &v9fs_dentry_operations;
|
sb->s_d_op = &v9fs_dentry_operations;
|
||||||
|
|
||||||
inode = v9fs_get_new_inode_from_fid(v9ses, fid, sb);
|
inode = v9fs_get_inode_from_fid(v9ses, fid, sb);
|
||||||
if (IS_ERR(inode)) {
|
if (IS_ERR(inode)) {
|
||||||
retval = PTR_ERR(inode);
|
retval = PTR_ERR(inode);
|
||||||
goto release_sb;
|
goto release_sb;
|
||||||
|
|
Loading…
Reference in a new issue