]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
wow, it mounts
authorsageweil <sageweil@29311d96-e01e-0410-9327-a35deaab8ce9>
Thu, 6 Dec 2007 00:49:16 +0000 (00:49 +0000)
committersageweil <sageweil@29311d96-e01e-0410-9327-a35deaab8ce9>
Thu, 6 Dec 2007 00:49:16 +0000 (00:49 +0000)
git-svn-id: https://ceph.svn.sf.net/svnroot/ceph@2182 29311d96-e01e-0410-9327-a35deaab8ce9

trunk/ceph/kernel/client.c
trunk/ceph/kernel/mds_client.c
trunk/ceph/kernel/mds_client.h
trunk/ceph/kernel/messenger.h
trunk/ceph/kernel/super.c
trunk/ceph/kernel/super.h

index 45f3d098da5a96af00b164a5c1b53181acfa2b83..010cf24cec240e93378f0129977785a1fcff0d8a 100644 (file)
@@ -88,7 +88,7 @@ fail:
 }
 
 /*
- * try to mount
+ * mount: join the ceph cluster.
  */
 static int mount(struct ceph_client *client, struct ceph_mount_args *args)
 {
index 161d1f9d15a32b257592c8bdb617f33db2960360..36f63feac85acf4252725d61ad16fbebcf3231a2 100644 (file)
@@ -42,7 +42,7 @@ static struct ceph_mds_request *
 register_request(struct ceph_mds_client *mdsc, struct ceph_msg *msg, int mds)
 {
        struct ceph_mds_request *req;
-       struct ceph_client_request_head *head = msg->front.iov_base;
+       struct ceph_mds_request_head *head = msg->front.iov_base;
 
        req = kmalloc(sizeof(*req), GFP_KERNEL);
        req->r_tid = head->tid = ++mdsc->last_tid;
@@ -252,19 +252,19 @@ void ceph_mdsc_init(struct ceph_mds_client *mdsc, struct ceph_client *client)
 
 
 struct ceph_msg *
-ceph_mdsc_create_request_msg(struct ceph_mds_client *mdsc, int op, 
-                            ceph_ino_t ino1, const char *path1, 
-                            ceph_ino_t ino2, const char *path2)
+ceph_mdsc_create_request(struct ceph_mds_client *mdsc, int op, 
+                        ceph_ino_t ino1, const char *path1, 
+                        ceph_ino_t ino2, const char *path2)
 {
        struct ceph_msg *req;
-       struct ceph_client_request_head *head;
+       struct ceph_mds_request_head *head;
        void *p, *end;
        int pathlen = 2*(sizeof(ino1) + sizeof(__u32));
        if (path1) pathlen += strlen(path1);
        if (path2) pathlen += strlen(path2);
 
        req = ceph_msg_new(CEPH_MSG_CLIENT_REQUEST, 
-                          sizeof(struct ceph_client_request_head) + pathlen,
+                          sizeof(struct ceph_mds_request_head) + pathlen,
                           0, 0);
        if (IS_ERR(req))
                return req;
@@ -356,17 +356,18 @@ retry:
        return reply;
 }
 
+/*
 int ceph_mdsc_do(struct ceph_mds_client *mdsc, int op, 
                 ceph_ino_t ino1, const char *path1, 
                 ceph_ino_t ino2, const char *path2)
 {
        struct ceph_msg *req, *reply;
-       struct ceph_client_reply_head *head;
+       struct ceph_mds_reply_head *head;
        int ret;
 
        dout(30, "mdsc do op %d on %llx/%s %llx/%s\n", op, ino1, 
             path1 ? path1:"", ino2, path2 ? path2:"");
-       req = ceph_mdsc_create_request_msg(mdsc, op, ino1, path1, ino2, path2);
+       req = ceph_mdsc_create_request(mdsc, op, ino1, path1, ino2, path2);
        if (IS_ERR(req)) 
                return PTR_ERR(req);
 
@@ -379,13 +380,14 @@ int ceph_mdsc_do(struct ceph_mds_client *mdsc, int op,
        ceph_msg_put(reply);
        return ret;
 }
+*/
 
 
 
 void ceph_mdsc_handle_reply(struct ceph_mds_client *mdsc, struct ceph_msg *msg)
 {
        struct ceph_mds_request *req;
-       struct ceph_client_reply_head *head = msg->front.iov_base;
+       struct ceph_mds_reply_head *head = msg->front.iov_base;
        __u64 tid;
 
        /* extract tid */
@@ -418,42 +420,22 @@ done:
 }
 
 
-struct reply_info_in {
-       struct ceph_client_reply_inode *in;
-       __u32 symlink_len;
-       char *symlink;
-};
-
-int parse_reply_info_in(void **p, void *end, struct reply_info_in *in)
+int parse_reply_info_in(void **p, void *end, struct ceph_mds_reply_info_in *info)
 {
        int err;
-       in->in = *p;
-       *p += sizeof(struct ceph_client_reply_inode) +
-               sizeof(__u32)*le32_to_cpu(in->in->fragtree.nsplits);
-       if ((err == ceph_decode_32(p, end, &in->symlink_len)) < 0)
+       info->in = *p;
+       *p += sizeof(struct ceph_mds_reply_inode) +
+               sizeof(__u32)*le32_to_cpu(info->in->fragtree.nsplits);
+       if ((err == ceph_decode_32(p, end, &info->symlink_len)) < 0)
                return err;
-       in->symlink = *p;
-       *p += in->symlink_len;
+       info->symlink = *p;
+       *p += info->symlink_len;
        if (unlikely(*p > end))
                return -EINVAL;
        return 0;
 }
 
-struct reply_info {
-       int trace_nr;
-       struct reply_info_in *trace_in;
-       struct ceph_client_reply_dirfrag **trace_dir;
-       char **trace_dname;
-       __u32 *trace_dname_len;
-
-       struct ceph_client_reply_dirfrag *dir_dir;
-       int dir_nr;
-       struct reply_info_in *dir_in;
-       char **dir_dname;
-       __u32 *dir_dname_len;
-};
-
-int parse_reply_info_trace(void **p, void *end, struct reply_info *info)
+int parse_reply_info_trace(void **p, void *end, struct ceph_mds_reply_info *info)
 {
        __u32 numi;
        int err = -EINVAL;
@@ -487,7 +469,7 @@ int parse_reply_info_trace(void **p, void *end, struct reply_info *info)
                        goto bad;
                /* dir */
                info->trace_dir[numi] = *p;
-               *p += sizeof(struct ceph_client_reply_dirfrag) +
+               *p += sizeof(struct ceph_mds_reply_dirfrag) +
                        sizeof(__u32)*le32_to_cpu(info->trace_dir[numi]->ndist);
                if (unlikely(*p > end))
                        goto bad;
@@ -503,7 +485,7 @@ bad:
        return err;
 }
 
-int parse_reply_info_dir(void **p, void *end, struct reply_info *info)
+int parse_reply_info_dir(void **p, void *end, struct ceph_mds_reply_info *info)
 {
        __u32 num, i = 0;
        int err = -EINVAL;
@@ -549,7 +531,7 @@ bad:
 }
 
 
-int parse_reply_info(struct ceph_msg *msg, struct reply_info *info)
+int ceph_mdsc_parse_reply_info(struct ceph_msg *msg, struct ceph_mds_reply_info *info)
 {
        void *p, *end;
        __u32 len;
@@ -558,7 +540,7 @@ int parse_reply_info(struct ceph_msg *msg, struct reply_info *info)
        memset(info, 0, sizeof(*info));
        
        /* trace */
-       p = msg->front.iov_base + sizeof(struct ceph_client_reply_head);
+       p = msg->front.iov_base + sizeof(struct ceph_mds_reply_head);
        end = p + msg->front.iov_len;
        if ((err = ceph_decode_32(&p, end, &len)) < 0)
                goto bad;
@@ -581,12 +563,62 @@ bad:
        return err;
 }
 
-void destroy_reply_info(struct reply_info *info)
+void ceph_mdsc_destroy_reply_info(struct ceph_mds_reply_info *info)
 {
        if (info->trace_in) kfree(info->trace_in);
        if (info->dir_in) kfree(info->dir_in);
 }
 
+
+void ceph_mdsc_fill_inode(struct inode *inode, struct ceph_mds_reply_inode *info)
+{
+       struct ceph_inode_info *ci = CEPH_I(inode);
+       int mask = le32_to_cpu(info->mask);
+       int i;
+
+       /* vfs inode */
+       inode->i_ino = le64_to_cpu(info->ino);
+       inode->i_mode = le32_to_cpu(info->mode) | S_IFDIR;
+       inode->i_uid = le32_to_cpu(info->uid);
+       inode->i_gid = le32_to_cpu(info->gid);
+       inode->i_nlink = le32_to_cpu(info->nlink);
+       inode->i_size = le64_to_cpu(info->size);
+       inode->i_rdev = le32_to_cpu(info->rdev);
+
+       dout(30, "mdsc fill_inode ino=%lx by %d.%d sz=%llu\n", inode->i_ino,
+            inode->i_uid, inode->i_gid, inode->i_size);
+       
+       ceph_decode_timespec(&inode->i_atime, &info->atime);
+       ceph_decode_timespec(&inode->i_mtime, &info->mtime);
+       ceph_decode_timespec(&inode->i_ctime, &info->ctime);
+       
+       /* ceph inode */
+       ci->i_layout = info->layout;  /* swab? */
+
+       if (le32_to_cpu(info->fragtree.nsplits) == 0) {
+               ci->i_fragtree = ci->i_fragtree_static;
+       } else {
+               //ci->i_fragtree = kmalloc(...);
+               BUG_ON(1); // write me
+       }
+       ci->i_fragtree->nsplits = le32_to_cpu(info->fragtree.nsplits);
+       for (i=0; i<ci->i_fragtree->nsplits; i++)
+               ci->i_fragtree->splits[i] = le32_to_cpu(info->fragtree.splits[i]);
+
+       ci->i_frag_map_nr = 1;
+       ci->i_frag_map = ci->i_frag_map_static;
+       ci->i_frag_map[0].frag = 0;
+       ci->i_frag_map[0].mds = 0; /* fixme */
+       
+       ci->i_nr_caps = 0;
+       ci->i_caps = ci->i_caps_static;
+       ci->i_wr_size = 0;
+       ci->i_wr_mtime.tv_sec = 0;
+       ci->i_wr_mtime.tv_usec = 0;
+}
+
+
+
 void ceph_mdsc_handle_forward(struct ceph_mds_client *mdsc, struct ceph_msg *msg)
 {
        struct ceph_mds_request *req;
index 7d3cf97f179e437d6ae1b61b94a7671711985d78..feac145ba4ae868186645ec5f69663e4e51ce37a 100644 (file)
@@ -44,6 +44,9 @@ struct ceph_mds_request {
 };
 
 
+/* 
+ * mds client state
+ */
 struct ceph_mds_client {
        spinlock_t lock;
 
@@ -61,13 +64,43 @@ struct ceph_mds_client {
        struct completion map_waiters;
 };
 
+/*
+ * for mds reply parsing
+ */
+struct ceph_mds_reply_info_in {
+       struct ceph_mds_reply_inode *in;
+       __u32 symlink_len;
+       char *symlink;
+};
+
+struct ceph_mds_reply_info {
+       int trace_nr;
+       struct ceph_mds_reply_info_in *trace_in;
+       struct ceph_mds_reply_dirfrag **trace_dir;
+       char **trace_dname;
+       __u32 *trace_dname_len;
+
+       struct ceph_mds_reply_dirfrag *dir_dir;
+       int dir_nr;
+       struct ceph_mds_reply_info_in *dir_in;
+       char **dir_dname;
+       __u32 *dir_dname_len;
+};
+
+
+
 extern void ceph_mdsc_init(struct ceph_mds_client *mdsc, struct ceph_client *client);
-struct ceph_msg *ceph_mdsc_do_request(struct ceph_mds_client *mdsc, struct ceph_msg *msg, int mds);
-int ceph_mdsc_do(struct ceph_mds_client *mdsc, int op, ceph_ino_t ino1, const char *path1, ceph_ino_t ino2, const char *path2);
 
 extern void ceph_mdsc_handle_map(struct ceph_mds_client *mdsc, struct ceph_msg *msg);
 extern void ceph_mdsc_handle_session(struct ceph_mds_client *mdsc, struct ceph_msg *msg);
 extern void ceph_mdsc_handle_reply(struct ceph_mds_client *mdsc, struct ceph_msg *msg);
 extern void ceph_mdsc_handle_forward(struct ceph_mds_client *mdsc, struct ceph_msg *msg);
 
+extern struct ceph_msg *ceph_mdsc_create_request(struct ceph_mds_client *mdsc, int op, ceph_ino_t ino1, const char *path1, ceph_ino_t ino2, const char *path2);
+struct ceph_msg *ceph_mdsc_do_request(struct ceph_mds_client *mdsc, struct ceph_msg *msg, int mds);
+
+
+extern int ceph_mdsc_parse_reply_info(struct ceph_msg *msg, struct ceph_mds_reply_info *info);
+extern void ceph_mdsc_fill_inode(struct inode *inode, struct ceph_mds_reply_inode *i);
+
 #endif
index 8a6168a5381d089528f06b287bad4d3bea08a7c2..b8c81a3b3d9c0bdc60c8b2510ceaadb94de36592 100644 (file)
@@ -238,6 +238,12 @@ static __inline__ int ceph_encode_filepath(void **p, void *end, ceph_ino_t ino,
        return 0;
 }
 
+static void __inline__ ceph_decode_timespec(struct timespec *ts, struct ceph_timeval *tv)
+{
+       ts->tv_sec = le32_to_cpu(tv->tv_sec);
+       ts->tv_nsec = 1000*le32_to_cpu(tv->tv_usec);
+}
+
 
 
 
index 224fe97a294a8a1bddf35143ee53dc5f5aa20a92..b5477214f34577ba828c3d98e406a5ed56b94b5d 100644 (file)
@@ -326,10 +326,70 @@ static int parse_mount_args(int flags, char *options, const char *dev_name, stru
 }
 
 
+static int open_root_inode(struct super_block *sb, struct ceph_mount_args *args)
+{
+       struct ceph_super_info *sbinfo = ceph_sbinfo(sb);
+       struct ceph_mds_client *mdsc = &sbinfo->sb_client->mdsc;
+       struct inode *inode;
+       struct dentry *root;
+       struct ceph_msg *req, *reply;
+       struct ceph_mds_reply_head *head;
+       struct ceph_mds_reply_info rinfo;
+       struct ceph_mds_reply_info_in *rootinfo;
+       int err;
+       
+       /* open dir */
+       dout(30, "open_root_inode opening '%s'\n", args->path);
+       req = ceph_mdsc_create_request(mdsc, CEPH_MDS_OP_OPEN, 1, args->path, 0, 0);
+       if (IS_ERR(req)) 
+               return PTR_ERR(req);
+       reply = ceph_mdsc_do_request(mdsc, req, -1);
+       if (IS_ERR(reply))
+               return PTR_ERR(reply);
+       
+       /* parse reply */
+       head = reply->front.iov_base;
+       err = le32_to_cpu(head->result);
+       dout(30, "open_root_inode open result=%d\n", err);
+       if (err < 0) {
+               dout(30, "open_root_inode mds reports %d", err);
+               goto out;
+       }
+       if ((err = ceph_mdsc_parse_reply_info(reply, &rinfo)) < 0) {
+               dout(30, "open_root_inode problem parsing reply %d", err);
+               goto out;
+       }
+       BUG_ON(rinfo.trace_nr == 0);
+       rootinfo = &rinfo.trace_in[rinfo.trace_nr-1];
+               
+       /* construct root inode */
+       inode = new_inode(sb);
+       if (!inode) {
+               err = -ENOMEM;
+               goto out;
+       }
+       dout(30, "open_root_inode filling inode\n");
+       ceph_mdsc_fill_inode(inode, rootinfo->in);
+       root = d_alloc_root(inode);
+       if (!root) {
+               err = -ENOMEM;
+               goto out2;
+       }
+       sb->s_root = root;
+       dout(30, "open_root_inode success.\n");
+       return 0;
+
+out2:
+       iput(inode);  /* ? */
+out:
+       ceph_msg_put(reply);
+       return err;     
+}
+
 static int ceph_get_sb(struct file_system_type *fs_type,
                       int flags, const char *dev_name, void *data, struct vfsmount *mnt)
 {
-       struct super_block *s;
+       struct super_block *sb;
        struct ceph_mount_args mount_args;
        struct ceph_super_info *sbinfo;
        int err;
@@ -345,12 +405,12 @@ static int ceph_get_sb(struct file_system_type *fs_type,
                compare_super = 0;
        
        /* superblock */
-       s = sget(fs_type, compare_super, ceph_set_super, &mount_args);
-       if (IS_ERR(s)) {
-               err = PTR_ERR(s);
+       sb = sget(fs_type, compare_super, ceph_set_super, &mount_args);
+       if (IS_ERR(sb)) {
+               err = PTR_ERR(sb);
                goto out;
        }
-       sbinfo = ceph_sbinfo(s);
+       sbinfo = ceph_sbinfo(sb);
 
        /* client */
        if (!sbinfo->sb_client) {
@@ -364,21 +424,18 @@ static int ceph_get_sb(struct file_system_type *fs_type,
        }
        
        /* open root */
-       dout(30, "ceph_get_sb opening base mountpoing\n");
-       err = ceph_mdsc_do(&sbinfo->sb_client->mdsc, CEPH_MDS_OP_OPEN,
-                          CEPH_INO_ROOT, mount_args.path, 0, 0);
-       if (err < 0)
-               return err;
-
-       /* construct root inode */
-       dout(30, "ceph_get_sb constructing root inode\n");
+       dout(30, "ceph_get_sb opening base mountpoint\n");
+       if ((err = open_root_inode(sb, &mount_args)) < 0) 
+               goto out_splat;
        
-       dout(30, "ceph_get_sb success\n");
-        return 0;
+       dout(30, "ceph_get_sb finishing\n");
+        return simple_set_mnt(mnt, sb);
        
 out_splat:
-       up_write(&s->s_umount);
-       deactivate_super(s);
+       if (sbinfo->sb_client)
+               ceph_put_client(sbinfo->sb_client);
+       up_write(&sb->s_umount);
+       deactivate_super(sb);
 out:
        dout(25, "ceph_get_sb fail %d\n", err);
        return err;
index 4da42ac81aa063659695dd880833ac1ddc184845..7940296e5428dd0b8e41d1301952d50b95c72e30 100644 (file)
@@ -57,10 +57,9 @@ struct ceph_inode_frag_map_item {
 struct ceph_inode_info {
        struct ceph_file_layout i_layout;
 
-       int i_dir_auth;
-       struct ceph_frag_tree_head *i_fragtree, i_fragtree_static;
+       struct ceph_frag_tree_head *i_fragtree, i_fragtree_static[1];
        int i_frag_map_nr;
-       struct ceph_inode_frag_map_item *i_frag_map;
+       struct ceph_inode_frag_map_item *i_frag_map, i_frag_map_static[1];
        
        int i_nr_caps;
        struct ceph_inode_cap *i_caps;