fs/9p: Add inode hashing
authorAneesh Kumar K.V <aneesh.kumar@linux.vnet.ibm.com>
Mon, 28 Feb 2011 11:34:01 +0000 (17:04 +0530)
committerEric Van Hensbergen <ericvh@gmail.com>
Tue, 15 Mar 2011 14:57:39 +0000 (09:57 -0500)
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>
fs/9p/acl.c
fs/9p/v9fs_vfs.h
fs/9p/vfs_inode.c
fs/9p/vfs_inode_dotl.c

index 1ee3434239c80b0be362b91a11e042e1cab970c3..515455296378324b6d0aadbe0314dd2bd0716337 100644 (file)
@@ -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)
 {
index c44aaa8bd2a3e421a6476ed7d8a32d25f444267f..ab72e66c2e0c0ba16f6ac37e8c294093ad3cfccc 100644 (file)
@@ -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 *);
index a0d65a398729be0d04863c1928da44420fcf1710..445dd283dc157713cbd715ea9fb1f0d8bec51738 100644 (file)
@@ -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;
@@ -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 "
@@ -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;
 }
 
 /*
@@ -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;
 }
 
 /**
index 1327464bb2bbeeef6848dec627fd1cb321a4372f..6f62320eda89c951121e8e90389c1319e4b318ee 100644 (file)
@@ -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;
 }
 
 /**