]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
kclient: fix fh_to_dentry; move build_path to mds_client.c
authorSage Weil <sage@newdream.net>
Thu, 19 Feb 2009 00:35:45 +0000 (16:35 -0800)
committerSage Weil <sage@newdream.net>
Thu, 19 Feb 2009 19:58:25 +0000 (11:58 -0800)
src/kernel/dir.c
src/kernel/export.c
src/kernel/mds_client.c
src/kernel/super.h

index 636fed7c02a1689cc9fb6fbded82fb05c96a884f..918f933eec901774fc19a580469824a4c42a0b6b 100644 (file)
@@ -29,87 +29,6 @@ struct dentry_operations ceph_dentry_ops;
 
 static int ceph_dentry_revalidate(struct dentry *dentry, struct nameidata *nd);
 
-/*
- * build a dentry's path.  allocate on heap; caller must kfree.  based
- * on build_path_from_dentry in fs/cifs/dir.c.
- *
- * encode hidden .snap dirs as a double /, i.e.
- *   foo/.snap/bar -> foo//bar
- */
-char *ceph_build_path(struct dentry *dentry, int *plen, u64 *base,
-                     int mds)
-{
-       struct dentry *temp;
-       char *path;
-       int len, pos;
-
-       if (dentry == NULL)
-               return ERR_PTR(-EINVAL);
-
-retry:
-       len = 0;
-       for (temp = dentry; !IS_ROOT(temp);) {
-               struct inode *inode = temp->d_inode;
-               if (inode && ceph_snap(inode) == CEPH_SNAPDIR)
-                       len++;  /* slash only */
-               else
-                       len += 1 + temp->d_name.len;
-               temp = temp->d_parent;
-               if (temp == NULL) {
-                       derr(1, "corrupt dentry %p\n", dentry);
-                       return ERR_PTR(-EINVAL);
-               }
-       }
-       if (len)
-               len--;  /* no leading '/' */
-
-       path = kmalloc(len+1, GFP_NOFS);
-       if (path == NULL)
-               return ERR_PTR(-ENOMEM);
-       pos = len;
-       path[pos] = 0;  /* trailing null */
-       for (temp = dentry; !IS_ROOT(temp) && pos != 0; ) {
-               if (temp->d_inode &&
-                   ceph_snap(temp->d_inode) == CEPH_SNAPDIR) {
-                       dout(50, "build_path_dentry path+%d: %p SNAPDIR\n",
-                            pos, temp);
-               } else {
-                       pos -= temp->d_name.len;
-                       if (pos < 0)
-                               break;
-                       strncpy(path + pos, temp->d_name.name,
-                               temp->d_name.len);
-                       dout(50, "build_path_dentry path+%d: %p '%.*s'\n",
-                            pos, temp, temp->d_name.len, path + pos);
-               }
-               if (pos)
-                       path[--pos] = '/';
-               temp = temp->d_parent;
-               if (temp == NULL) {
-                       derr(1, "corrupt dentry\n");
-                       kfree(path);
-                       return ERR_PTR(-EINVAL);
-               }
-       }
-       if (pos != 0) {
-               derr(1, "did not end path lookup where expected, "
-                    "namelen is %d, pos is %d\n", len, pos);
-               /* presumably this is only possible if racing with a
-                  rename of one of the parent directories (we can not
-                  lock the dentries above us to prevent this, but
-                  retrying should be harmless) */
-               kfree(path);
-               goto retry;
-       }
-
-       *base = ceph_ino(temp->d_inode);
-       *plen = len;
-       dout(10, "build_path_dentry on %p %d built %llx '%.*s'\n",
-            dentry, atomic_read(&dentry->d_count), *base, len, path);
-       return path;
-}
-
-
 /*
  * for readdir, encoding the directory frag and offset within that frag
  * into f_pos.
index 5c9783d39b675dbf5e9aab571a28ae5d808c997e..a6e3537fd0500a54e8acdac218a8077b6a56b7c3 100644 (file)
@@ -79,19 +79,17 @@ static struct dentry *__fh_to_dentry(struct super_block *sb,
 
        inode = ceph_find_inode(sb, vino);
        if (!inode) {
-#warning fixme
-               /*
                struct ceph_mds_request *req;
                derr(10, "fh_to_dentry %llx.%x -- no inode\n", vino.ino, hash);
                req = ceph_mdsc_create_request(mdsc,
                                               CEPH_MDS_OP_FINDINODE,
-                                              len, (char *)fh, 0, NULL,
-                                              NULL, USE_ANY_MDS);
+                                              NULL, NULL,
+                                              (char *)fh, (void *)&len,
+                                              USE_ANY_MDS);
                if (IS_ERR(req))
                        return ERR_PTR(PTR_ERR(req));
                err = ceph_mdsc_do_request(mdsc, NULL, req);
                ceph_mdsc_put_request(req);
-               */
                inode = ceph_find_inode(sb, vino);
                if (!inode)
                        return ERR_PTR(err ? err : -ESTALE);
index 7753a59505ea3bd038e04b46c424173e58cb85be..df01837c6d842989383373c86c519a86ec0d0b10 100644 (file)
@@ -869,7 +869,7 @@ ceph_mdsc_create_request(struct ceph_mds_client *mdsc, int op,
        if (old_dentry)
                req->r_old_dentry = dget(old_dentry);
        req->r_path1 = path1;
-       req->r_path2 = path2;   
+       req->r_path2 = path2;
        req->r_direct_mode = mode;
        return req;
 }
@@ -888,6 +888,86 @@ static u64 __get_oldest_tid(struct ceph_mds_client *mdsc)
        return first->r_tid;
 }
 
+/*
+ * build a dentry's path.  allocate on heap; caller must kfree.  based
+ * on build_path_from_dentry in fs/cifs/dir.c.
+ *
+ * encode hidden .snap dirs as a double /, i.e.
+ *   foo/.snap/bar -> foo//bar
+ */
+static char *build_path(struct dentry *dentry, int *plen, u64 *base, int mds)
+{
+       struct dentry *temp;
+       char *path;
+       int len, pos;
+
+       if (dentry == NULL)
+               return ERR_PTR(-EINVAL);
+
+retry:
+       len = 0;
+       for (temp = dentry; !IS_ROOT(temp);) {
+               struct inode *inode = temp->d_inode;
+               if (inode && ceph_snap(inode) == CEPH_SNAPDIR)
+                       len++;  /* slash only */
+               else
+                       len += 1 + temp->d_name.len;
+               temp = temp->d_parent;
+               if (temp == NULL) {
+                       derr(1, "corrupt dentry %p\n", dentry);
+                       return ERR_PTR(-EINVAL);
+               }
+       }
+       if (len)
+               len--;  /* no leading '/' */
+
+       path = kmalloc(len+1, GFP_NOFS);
+       if (path == NULL)
+               return ERR_PTR(-ENOMEM);
+       pos = len;
+       path[pos] = 0;  /* trailing null */
+       for (temp = dentry; !IS_ROOT(temp) && pos != 0; ) {
+               if (temp->d_inode &&
+                   ceph_snap(temp->d_inode) == CEPH_SNAPDIR) {
+                       dout(50, "build_path_dentry path+%d: %p SNAPDIR\n",
+                            pos, temp);
+               } else {
+                       pos -= temp->d_name.len;
+                       if (pos < 0)
+                               break;
+                       strncpy(path + pos, temp->d_name.name,
+                               temp->d_name.len);
+                       dout(50, "build_path_dentry path+%d: %p '%.*s'\n",
+                            pos, temp, temp->d_name.len, path + pos);
+               }
+               if (pos)
+                       path[--pos] = '/';
+               temp = temp->d_parent;
+               if (temp == NULL) {
+                       derr(1, "corrupt dentry\n");
+                       kfree(path);
+                       return ERR_PTR(-EINVAL);
+               }
+       }
+       if (pos != 0) {
+               derr(1, "did not end path lookup where expected, "
+                    "namelen is %d, pos is %d\n", len, pos);
+               /* presumably this is only possible if racing with a
+                  rename of one of the parent directories (we can not
+                  lock the dentries above us to prevent this, but
+                  retrying should be harmless) */
+               kfree(path);
+               goto retry;
+       }
+
+       *base = ceph_ino(temp->d_inode);
+       *plen = len;
+       dout(10, "build_path_dentry on %p %d built %llx '%.*s'\n",
+            dentry, atomic_read(&dentry->d_count), *base, len, path);
+       return path;
+}
+
+
 /*
  * called under mdsc->mutex
  */
@@ -901,21 +981,30 @@ static struct ceph_msg *create_request_message(struct ceph_mds_client *mdsc,
        const char *path2 = req->r_path2;
        u64 ino1 = 1, ino2 = 0;
        int pathlen1 = 0, pathlen2 = 0;
+       int pathlen;
        void *p, *end;
+       u32 fhlen = 0;
 
-       if (path1)
-               pathlen1 = strlen(path1);
-       else
-               path1 = ceph_build_path(req->r_dentry, &pathlen1, &ino1, mds);
-       if (path2)
-               pathlen2 = strlen(path2);
-       else if (req->r_old_dentry)
-               path2 = ceph_build_path(req->r_old_dentry, &pathlen2, &ino2,
-                                       mds);
-
-       msg = ceph_msg_new(CEPH_MSG_CLIENT_REQUEST,
-                          sizeof(*head) + pathlen1 + pathlen2 +
-                          2*(sizeof(u32)+sizeof(u64)), 0, 0, NULL);
+       if (req->r_op == CEPH_MDS_OP_FINDINODE) {
+               fhlen = *(int *)req->r_path2;
+               path2 = 0;
+               pathlen = sizeof(u32) + fhlen*sizeof(struct ceph_inopath_item);
+       } else {
+               if (path1)
+                       pathlen1 = strlen(path1);
+               else
+                       path1 = build_path(req->r_dentry, &pathlen1, &ino1,
+                                          mds);
+               if (path2)
+                       pathlen2 = strlen(path2);
+               else if (req->r_old_dentry)
+                       path2 = build_path(req->r_old_dentry, &pathlen2, &ino2,
+                                          mds);
+               pathlen = pathlen1 + pathlen2 + 2*(sizeof(u32) + sizeof(u64));
+       }
+
+       msg = ceph_msg_new(CEPH_MSG_CLIENT_REQUEST, sizeof(*head) + pathlen,
+                          0, 0, NULL);
        if (IS_ERR(msg))
                goto out;
 
@@ -931,14 +1020,20 @@ static struct ceph_msg *create_request_message(struct ceph_mds_client *mdsc,
        head->caller_gid = cpu_to_le32(current->fsgid);
        head->args = req->r_args;
 
-       ceph_encode_filepath(&p, end, ino1, path1);
-       ceph_encode_filepath(&p, end, ino2, path2);
-       if (path1)
-               dout(10, "create_request_message path1 %llx/%s\n",
-                    ino1, path1);
-       if (path2)
-               dout(10, "create_request_message path2 %llx/%s\n",
-                    ino2, path2);
+       if (req->r_op == CEPH_MDS_OP_FINDINODE) {
+               ceph_encode_32(&p, fhlen);
+               memcpy(p, path1, fhlen * sizeof(struct ceph_inopath_item));
+               p += fhlen * sizeof(struct ceph_inopath_item);
+       } else {
+               ceph_encode_filepath(&p, end, ino1, path1);
+               ceph_encode_filepath(&p, end, ino2, path2);
+               if (path1)
+                       dout(10, "create_request_message path1 %llx/%s\n",
+                            ino1, path1);
+               if (path2)
+                       dout(10, "create_request_message path2 %llx/%s\n",
+                            ino2, path2);
+       }
 
        BUG_ON(p != end);
 
@@ -1584,8 +1679,7 @@ retry:
 
                dentry = d_find_alias(inode);
                if (dentry) {
-                       path = ceph_build_path(dentry, &pathlen,
-                                              &pathbase, 9999);
+                       path = build_path(dentry, &pathlen, &pathbase, -1);
                        if (IS_ERR(path)) {
                                err = PTR_ERR(path);
                                BUG_ON(err);
index 136ed6e183d504d72c0d571bd3f31dce44d35983..84aa5e0fe4ffa23d817f27717bf9cf60b34d8846 100644 (file)
@@ -760,7 +760,6 @@ extern const struct inode_operations ceph_dir_iops;
 extern struct dentry_operations ceph_dentry_ops, ceph_snap_dentry_ops,
        ceph_snapdir_dentry_ops;
 
-extern char *ceph_build_path(struct dentry *dn, int *len, u64 *base, int min);
 extern struct dentry *ceph_do_lookup(struct super_block *sb,
                                     struct dentry *dentry,
                                     int mask, int on_inode, int locked_dir);