Merge tag '9p-for-6.9' of git://git.kernel.org/pub/scm/linux/kernel/git/ericvh/v9fs
[linux-2.6-block.git] / fs / 9p / vfs_inode.c
index 32572982f72e68a6db3967d9ab9ba9d51c8bae9c..360a5304ec03ce53e5bab61e2177a5f325569ebf 100644 (file)
@@ -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;
@@ -331,36 +334,6 @@ error:
 
 }
 
-/**
- * v9fs_get_inode - helper function to setup an inode
- * @sb: superblock
- * @mode: mode to setup inode with
- * @rdev: The device numbers to set
- */
-
-struct inode *v9fs_get_inode(struct super_block *sb, umode_t mode, dev_t rdev)
-{
-       int err;
-       struct inode *inode;
-       struct v9fs_session_info *v9ses = sb->s_fs_info;
-
-       p9_debug(P9_DEBUG_VFS, "super block: %p mode: %ho\n", sb, mode);
-
-       inode = new_inode(sb);
-       if (!inode) {
-               pr_warn("%s (%d): Problem allocating inode\n",
-                       __func__, task_pid_nr(current));
-               return ERR_PTR(-ENOMEM);
-       }
-       err = v9fs_init_inode(v9ses, inode, mode, rdev);
-       if (err) {
-               iput(inode);
-               return ERR_PTR(err);
-       }
-       v9fs_set_netfs_context(inode);
-       return inode;
-}
-
 /**
  * v9fs_evict_inode - Remove an inode from the inode cache
  * @inode: inode to release
@@ -384,82 +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;
-       unsigned long i_ino;
        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;
-
-       i_ino = v9fs_qid2ino(qid);
-       inode = iget5_locked(sb, i_ino, 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 = i_ino;
+       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);
@@ -470,23 +401,6 @@ error:
 
 }
 
-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.
@@ -633,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,
@@ -761,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
@@ -1186,26 +1098,6 @@ v9fs_stat2inode(struct p9_wstat *stat, struct inode *inode,
        v9inode->cache_validity &= ~V9FS_INO_INVALID_ATTR;
 }
 
-/**
- * v9fs_qid2ino - convert qid into inode number
- * @qid: qid to hash
- *
- * BUG: potential for inode number collisions?
- */
-
-ino_t v9fs_qid2ino(struct p9_qid *qid)
-{
-       u64 path = qid->path + 2;
-       ino_t i = 0;
-
-       if (sizeof(ino_t) == sizeof(path))
-               memcpy(&i, &path, sizeof(ino_t));
-       else
-               i = (ino_t) (path ^ (path >> 32));
-
-       return i;
-}
-
 /**
  * v9fs_vfs_get_link - follow a symlink path
  * @dentry: dentry for symlink