diff options
Diffstat (limited to 'fs/9p/vfs_inode_dotl.c')
-rw-r--r-- | fs/9p/vfs_inode_dotl.c | 194 |
1 files changed, 35 insertions, 159 deletions
diff --git a/fs/9p/vfs_inode_dotl.c b/fs/9p/vfs_inode_dotl.c index 3505227e1704..ef9db3e03506 100644 --- a/fs/9p/vfs_inode_dotl.c +++ b/fs/9p/vfs_inode_dotl.c @@ -52,78 +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; - unsigned long i_ino; 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; - i_ino = v9fs_qid2ino(qid); - inode = iget5_locked(sb, i_ino, 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 = i_ino; - 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; @@ -135,6 +90,7 @@ static struct inode *v9fs_qid_iget_dotl(struct super_block *sb, goto error; unlock_new_inode(inode); + return inode; error: iget_failed(inode); @@ -142,22 +98,6 @@ error: } -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; @@ -307,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); @@ -402,32 +342,17 @@ static int v9fs_vfs_mkdir_dotl(struct mnt_idmap *idmap, } /* instantiate inode and assign the unopened fid to the dentry */ - if (v9ses->cache & (CACHE_META|CACHE_LOOSE)) { - inode = v9fs_get_new_inode_from_fid(v9ses, fid, dir->i_sb); - if (IS_ERR(inode)) { - err = PTR_ERR(inode); - p9_debug(P9_DEBUG_VFS, "inode creation failed %d\n", - err); - goto error; - } - v9fs_fid_add(dentry, &fid); - v9fs_set_create_acl(inode, fid, dacl, pacl); - d_instantiate(dentry, inode); - err = 0; - } else { - /* - * Not in cached mode. No need to populate - * inode with stat. We need to get an inode - * so that we can set the acl with dentry - */ - inode = v9fs_get_inode(dir->i_sb, mode, 0); - if (IS_ERR(inode)) { - err = PTR_ERR(inode); - goto error; - } - v9fs_set_create_acl(inode, fid, dacl, pacl); - d_instantiate(dentry, inode); + 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); + goto error; } + v9fs_fid_add(dentry, &fid); + v9fs_set_create_acl(inode, fid, dacl, pacl); + d_instantiate(dentry, inode); + err = 0; inc_nlink(dir); v9fs_invalidate_inode_attr(dir); error: @@ -709,14 +634,11 @@ v9fs_vfs_symlink_dotl(struct mnt_idmap *idmap, struct inode *dir, kgid_t gid; const unsigned char *name; struct p9_qid qid; - struct inode *inode; struct p9_fid *dfid; struct p9_fid *fid = NULL; - struct v9fs_session_info *v9ses; name = dentry->d_name.name; p9_debug(P9_DEBUG_VFS, "%lu,%s,%s\n", dir->i_ino, name, symname); - v9ses = v9fs_inode2v9ses(dir); dfid = v9fs_parent_fid(dentry); if (IS_ERR(dfid)) { @@ -736,36 +658,6 @@ v9fs_vfs_symlink_dotl(struct mnt_idmap *idmap, struct inode *dir, } v9fs_invalidate_inode_attr(dir); - if (v9ses->cache & (CACHE_META|CACHE_LOOSE)) { - /* Now walk from the parent so we can get an unopened fid. */ - fid = p9_client_walk(dfid, 1, &name, 1); - if (IS_ERR(fid)) { - err = PTR_ERR(fid); - p9_debug(P9_DEBUG_VFS, "p9_client_walk failed %d\n", - err); - goto error; - } - - /* instantiate inode and assign the unopened fid to dentry */ - inode = v9fs_get_new_inode_from_fid(v9ses, fid, dir->i_sb); - if (IS_ERR(inode)) { - err = PTR_ERR(inode); - p9_debug(P9_DEBUG_VFS, "inode creation failed %d\n", - err); - goto error; - } - v9fs_fid_add(dentry, &fid); - d_instantiate(dentry, inode); - err = 0; - } else { - /* Not in cached mode. No need to populate inode with stat */ - inode = v9fs_get_inode(dir->i_sb, S_IFLNK, 0); - if (IS_ERR(inode)) { - err = PTR_ERR(inode); - goto error; - } - d_instantiate(dentry, inode); - } error: p9_fid_put(fid); @@ -888,33 +780,17 @@ v9fs_vfs_mknod_dotl(struct mnt_idmap *idmap, struct inode *dir, err); goto error; } - - /* instantiate inode and assign the unopened fid to the dentry */ - if (v9ses->cache & (CACHE_META|CACHE_LOOSE)) { - inode = v9fs_get_new_inode_from_fid(v9ses, fid, dir->i_sb); - if (IS_ERR(inode)) { - err = PTR_ERR(inode); - p9_debug(P9_DEBUG_VFS, "inode creation failed %d\n", - err); - goto error; - } - v9fs_set_create_acl(inode, fid, dacl, pacl); - v9fs_fid_add(dentry, &fid); - d_instantiate(dentry, inode); - err = 0; - } else { - /* - * Not in cached mode. No need to populate inode with stat. - * socket syscall returns a fd, so we need instantiate - */ - inode = v9fs_get_inode(dir->i_sb, mode, rdev); - if (IS_ERR(inode)) { - err = PTR_ERR(inode); - goto error; - } - v9fs_set_create_acl(inode, fid, dacl, pacl); - d_instantiate(dentry, inode); + 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); + goto error; } + v9fs_set_create_acl(inode, fid, dacl, pacl); + v9fs_fid_add(dentry, &fid); + d_instantiate(dentry, inode); + err = 0; error: p9_fid_put(fid); v9fs_put_acl(dacl, pacl); |