Skip to content

Commit

Permalink
fs/9p: simplify iget to remove unnecessary paths
Browse files Browse the repository at this point in the history
Remove the additional comparison operators and switch to
simply lookup by inode number (aka qid.path).

Signed-off-by: Eric Van Hensbergen <[email protected]>
  • Loading branch information
ericvh committed Jan 26, 2024
1 parent b91a266 commit 724a084
Show file tree
Hide file tree
Showing 5 changed files with 45 additions and 180 deletions.
31 changes: 5 additions & 26 deletions fs/9p/v9fs.h
Original file line number Diff line number Diff line change
Expand Up @@ -179,16 +179,13 @@ extern int v9fs_vfs_rename(struct mnt_idmap *idmap,
struct inode *old_dir, struct dentry *old_dentry,
struct inode *new_dir, struct dentry *new_dentry,
unsigned int flags);
extern struct inode *v9fs_inode_from_fid(struct v9fs_session_info *v9ses,
struct p9_fid *fid,
struct super_block *sb, int new);
extern struct inode *v9fs_fid_iget(struct super_block *sb, struct p9_fid *fid);
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 const struct netfs_request_ops v9fs_req_ops;
extern struct inode *v9fs_inode_from_fid_dotl(struct v9fs_session_info *v9ses,
struct p9_fid *fid,
struct super_block *sb, int new);
extern struct inode *v9fs_fid_iget_dotl(struct super_block *sb,
struct p9_fid *fid);

/* other default globals */
#define V9FS_PORT 564
Expand Down Expand Up @@ -230,27 +227,9 @@ 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, 0);
return v9fs_fid_iget_dotl(sb, fid);
else
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);
return v9fs_fid_iget(sb, fid);
}

#endif
2 changes: 1 addition & 1 deletion fs/9p/v9fs_vfs.h
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ struct inode *v9fs_alloc_inode(struct super_block *sb);
void v9fs_free_inode(struct inode *inode);
void v9fs_set_netfs_context(struct inode *inode);
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);
#if (BITS_PER_LONG == 32)
#define QID2INO(q) ((ino_t) (((q)->path+2) ^ (((q)->path) >> 32)))
Expand Down
98 changes: 21 additions & 77 deletions fs/9p/vfs_inode.c
Original file line number Diff line number Diff line change
Expand Up @@ -253,9 +253,12 @@ void v9fs_set_netfs_context(struct inode *inode)
}

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;
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->i_blocks = 0;
Expand Down Expand Up @@ -354,80 +357,40 @@ void v9fs_evict_inode(struct inode *inode)
#endif
}

static int v9fs_test_inode(struct inode *inode, void *data)
{
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)
struct inode *v9fs_fid_iget(struct super_block *sb, struct p9_fid *fid)
{
dev_t rdev;
int retval;
umode_t umode;
struct inode *inode;
struct p9_wstat *st;
struct v9fs_session_info *v9ses = sb->s_fs_info;
int (*test)(struct inode *inode, void *data);

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

inode = iget5_locked(sb, QID2INO(qid), test, v9fs_set_inode, st);
if (!inode)
inode = iget_locked(sb, QID2INO(&fid->qid));
if (unlikely(!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.
*/
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);
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)
goto error;

v9fs_stat2inode(st, inode, sb, 0);
v9fs_set_netfs_context(inode);
v9fs_cache_inode_get_cookie(inode);
unlock_new_inode(inode);
Expand All @@ -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
* plan 9 AT flag.
Expand Down Expand Up @@ -601,7 +547,7 @@ v9fs_create(struct v9fs_session_info *v9ses, struct inode *dir,
/*
* 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)) {
err = PTR_ERR(inode);
p9_debug(P9_DEBUG_VFS,
Expand Down Expand Up @@ -729,10 +675,8 @@ struct dentry *v9fs_vfs_lookup(struct inode *dir, struct dentry *dentry,
inode = NULL;
else if (IS_ERR(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
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
* for the new name, then make sure we instantiate with
Expand Down
92 changes: 17 additions & 75 deletions fs/9p/vfs_inode_dotl.c
Original file line number Diff line number Diff line change
Expand Up @@ -52,76 +52,33 @@ static kgid_t v9fs_get_fsgid_for_create(struct inode *dir_inode)
return current_fsgid();
}

static int v9fs_test_inode_dotl(struct inode *inode, void *data)
{
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)
struct inode *v9fs_fid_iget_dotl(struct super_block *sb, struct p9_fid *fid)
{
int retval;
struct inode *inode;
struct p9_stat_dotl *st;
struct v9fs_session_info *v9ses = sb->s_fs_info;
int (*test)(struct inode *inode, void *data);

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

inode = iget5_locked(sb, QID2INO(qid), test, v9fs_set_inode_dotl, st);
if (!inode)
inode = iget_locked(sb, QID2INO(&fid->qid));
if (unlikely(!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.
*/
inode->i_ino = QID2INO(qid);
retval = v9fs_init_inode(v9ses, inode,
st = p9_client_getattr_dotl(fid, P9_STATS_BASIC | P9_STATS_GEN);
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));
kfree(st);
if (retval)
goto error;

Expand All @@ -133,29 +90,14 @@ static struct inode *v9fs_qid_iget_dotl(struct super_block *sb,
goto error;

unlock_new_inode(inode);

return inode;
error:
iget_failed(inode);
return ERR_PTR(retval);

}

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 {
int open_flag;
int dotl_flag;
Expand Down Expand Up @@ -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);
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)) {
err = PTR_ERR(inode);
p9_debug(P9_DEBUG_VFS, "inode creation failed %d\n", err);
Expand Down Expand Up @@ -400,7 +342,7 @@ static int v9fs_vfs_mkdir_dotl(struct mnt_idmap *idmap,
}

/* 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)) {
err = PTR_ERR(inode);
p9_debug(P9_DEBUG_VFS, "inode creation failed %d\n",
Expand Down Expand Up @@ -838,7 +780,7 @@ v9fs_vfs_mknod_dotl(struct mnt_idmap *idmap, struct inode *dir,
err);
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)) {
err = PTR_ERR(inode);
p9_debug(P9_DEBUG_VFS, "inode creation failed %d\n",
Expand Down
2 changes: 1 addition & 1 deletion fs/9p/vfs_super.c
Original file line number Diff line number Diff line change
Expand Up @@ -139,7 +139,7 @@ static struct dentry *v9fs_mount(struct file_system_type *fs_type, int flags,
else
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)) {
retval = PTR_ERR(inode);
goto release_sb;
Expand Down

0 comments on commit 724a084

Please sign in to comment.