]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
client reply decoding bits
authorsageweil <sageweil@29311d96-e01e-0410-9327-a35deaab8ce9>
Mon, 19 Nov 2007 17:33:38 +0000 (17:33 +0000)
committersageweil <sageweil@29311d96-e01e-0410-9327-a35deaab8ce9>
Mon, 19 Nov 2007 17:33:38 +0000 (17:33 +0000)
git-svn-id: https://ceph.svn.sf.net/svnroot/ceph@2081 29311d96-e01e-0410-9327-a35deaab8ce9

trunk/ceph/include/ceph_fs.h
trunk/ceph/kernel/mds_client.c
trunk/ceph/kernel/messenger.h
trunk/ceph/messages/MClientReply.h

index 93f3c49e5230825447709e9c6d7655e1243973eb..dc6925da6be33b73629ab1464180d64b3d0f8c06 100644 (file)
@@ -146,11 +146,6 @@ struct ceph_object_extent {
 
 
 
-struct ceph_frag_tree {
-
-};
-
-
 
 /*********************************************
  * message types
@@ -328,6 +323,11 @@ struct ceph_client_reply_head {
        __u64 mdsmap_epoch;
 };
 
+struct ceph_frag_tree_head {
+       __u32 nsplits;
+       __s32 splits[0];
+};
+
 struct ceph_client_reply_inode {
        ceph_ino_t ino;
        struct ceph_file_layout layout;
@@ -337,15 +337,15 @@ struct ceph_client_reply_inode {
        __u64 size;
        __u32 rdev;
        __u32 mask;
-       char *symlink;
+       struct ceph_frag_tree_head fragtree;
 };
-/* followed by symlink string, then dirfragtree */
+/* followed by frag array, then symlink string */
 
 struct ceph_client_reply_dirfrag {
        __u32 frag;
        __s32 auth;
-       unsigned char is_rep;
-       int ndist;
+       __u8 is_rep;
+       __u32 ndist;
        __u32 dist[];
 };
 
index d39090c9a3fa0f63a7e0b45f59d94aef996d2c68..961e9ad03b58826e079d3299fdc63f0c29dd9f70 100644 (file)
@@ -242,7 +242,7 @@ ceph_mdsc_create_request_msg(struct ceph_mds_client *mdsc, int op,
 
        req = ceph_msg_new(CEPH_MSG_CLIENT_REQUEST, 
                           sizeof(struct ceph_client_request_head) +
-                          sizeof(ino1)*2 + sizeof(__u32)*2 + strlen(path) + strlen(path2)
+                          sizeof(ino1)*2 + sizeof(__u32)*2 + strlen(path1) + strlen(path2),
                           0, 0);
        if (IS_ERR(req))
                return req;
@@ -334,7 +334,6 @@ 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;
        __u64 tid;
-       int result;
 
        /* extract tid */
        if (msg->front.iov_len < sizeof(*head)) {
@@ -365,61 +364,89 @@ done:
        return;
 }
 
+
+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 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)
+               return err;
+       in->symlink = *p;
+       *p += in->symlink_len;
+       if (unlikely(*p > end))
+               return -EINVAL;
+       return 0;
+}
+
 struct reply_info {
        int trace_nr;
-       struct ceph_client_reply_inode **trace_in;
-       struct ceph_client_reply_dir **trace_dir;
+       struct reply_info_in *trace_in;
+       struct ceph_client_reply_dirfrag **trace_dir;
        char **trace_dname;
        __u32 *trace_dname_len;
 
-       struct ceph_client_reply_dir *dir_dir;
+       struct ceph_client_reply_dirfrag *dir_dir;
        int dir_nr;
-       struct ceph_client_reply_inode **dir_in;
+       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)
 {
-       __u32 numi, i = 0;
+       __u32 numi;
        int err = -EINVAL;
 
-       if ((err = ceph_decode_32(&p, end, &numi)) < 0)
+       if ((err = ceph_decode_32(p, end, &numi)) < 0)
                goto bad;
        if (numi == 0) 
                goto done;   /* hrm, this shouldn't actually happen, but.. */
        
        /* alloc one longer shared array */
        info->trace_nr = numi;
-       info->trace_in = kmalloc(4 * numi * sizeof(void*), GFP_KERNEL);
+       info->trace_in = kmalloc(numi * (2*sizeof(void*)+sizeof(*info->trace_in)), GFP_KERNEL);
        if (info->trace_in == NULL)
                return -ENOMEM;
-       info->trace_dir = info->trace_in + numi;
-       info->trace_dname = info->trace_in + numi*2;
-       info->trace_dname_len = info->trace_in + numi*3;
+       info->trace_dir = (void*)(info->trace_in + numi);
+       info->trace_dname = (void*)(info->trace_dir + numi);
+       info->trace_dname_len = (void*)(info->trace_dname + numi);
 
        while (1) {
                /* inode */
-               info->trace_in[numi-1] = p;
-               p += sizeof(struct ceph_client_reply_inode);
+               if ((err = parse_reply_info_in(p, end, &info->trace_in[numi-1])) < 0)
+                       goto bad;
                if (--numi == 0)
                        break;
-               
-               if ((err == ceph_decode_32(&p, end, &info->trace_dname_len[numi])) < 0)
+               /* dentry */
+               if ((err == ceph_decode_32(p, end, &info->trace_dname_len[numi])) < 0)
+                       goto bad;
+               info->trace_dname[numi] = *p;
+               *p += info->trace_dname_len[numi];
+               if (*p > end)
                        goto bad;
-               info->trace_dname[numi] = p;
-               p += info->trace_dname_len[numi];
-               if (p > end)
+               /* dir */
+               info->trace_dir[numi] = *p;
+               *p += sizeof(struct ceph_client_reply_dirfrag) +
+                       sizeof(__u32)*le32_to_cpu(info->trace_dir[numi]->ndist);
+               if (unlikely(*p > end))
                        goto bad;
        }
 
 done:
-       if (p != end)
-               return bad;
+       if (*p != end)
+               return -EINVAL;
        return 0;
        
 bad:
-       derr(1, "problem parsing trace %d %s\n", err, strerror(err));
+       derr(1, "problem parsing trace %d\n", err);
        return err;
 }
 
@@ -428,12 +455,12 @@ int parse_reply_info_dir(void **p, void *end, struct reply_info *info)
        __u32 num, i = 0;
        int err = -EINVAL;
 
-       info->dir_dir = p;
-       p += sizeof(*info->dir_dir);
-       if (p > end) 
+       info->dir_dir = *p;
+       *p += sizeof(*info->dir_dir) + sizeof(__u32)*info->dir_dir->ndist;
+       if (*p > end) 
                goto bad;
 
-       if ((err = ceph_decode_32(&p, end, &num)) < 0)
+       if ((err = ceph_decode_32(p, end, &num)) < 0)
                goto bad;
        if (num == 0)
                goto done;
@@ -443,19 +470,18 @@ int parse_reply_info_dir(void **p, void *end, struct reply_info *info)
        info->dir_in = kmalloc(3 * num * sizeof(void*), GFP_KERNEL);
        if (info->dir_in == NULL)
                return -ENOMEM;
-       info->dir_dname = info->trace_in + num;
-       info->dir_dname_len = info->trace_in + num*2;
+       info->dir_dname = (void*)(info->trace_in + num);
+       info->dir_dname_len = (void*)(info->trace_in + num*2);
 
        while (num) {
-               if ((err == ceph_decode_32(&p, end, &info->dir_dname_len[i])) < 0)
+               /* dentry, inode */
+               if ((err == ceph_decode_32(p, end, &info->dir_dname_len[i])) < 0)
                        goto bad;
-               info->dir_dname[i] = p;
-               p += info->dir_dname_len[i];
-               if (p > end)
+               info->dir_dname[i] = *p;
+               *p += info->dir_dname_len[i];
+               if (*p > end)
                        goto bad;
-               info->dir_in[i] = p;
-               p += sizeof(struct ceph_reply_inode_info);
-               if (p > end)
+               if ((err = parse_reply_info_in(p, end, &info->dir_in[i])) < 0)
                        goto bad;
                i++;
                num--;
@@ -465,7 +491,7 @@ done:
        return 0;
 
 bad:
-       derr(1, "problem parsing dir contents %d %s\n", err, strerror(err));
+       derr(1, "problem parsing dir contents %d\n", err);
        return err;
 }
 
@@ -473,7 +499,7 @@ bad:
 int parse_reply_info(struct ceph_msg *msg, struct reply_info *info)
 {
        void *p, *end;
-       __u32 len, numi = 0;
+       __u32 len;
        int err = -EINVAL;
 
        memset(info, 0, sizeof(*info));
@@ -497,7 +523,7 @@ int parse_reply_info(struct ceph_msg *msg, struct reply_info *info)
 
        return 0;
 bad:
-       derr(1, "problem parsing reply info %d %s\n", err, strerror(err));
+       derr(1, "problem parsing reply info %d\n", err);
        return err;
 }
 
index 5b6670073cf84b357a9f2b6b5599b6777e68bd2d..1aacd77724c0f5590279a168f032b0022df80953 100644 (file)
@@ -118,28 +118,28 @@ extern int ceph_msg_send(struct ceph_messenger *msgr, struct ceph_msg *msg);
 
 /* encoding/decoding helpers */
 static __inline__ int ceph_decode_64(void **p, void *end, __u64 *v) {
-       if (*p + sizeof(*v) > end)
+       if (unlikely(*p + sizeof(*v) > end))
                return -EINVAL;
        *v = le64_to_cpu(*(__u64*)p);
        p += sizeof(*v);
        return 0;
 }
 static __inline__ int ceph_decode_32(void **p, void *end, __u32 *v) {
-       if (*p + sizeof(*v) > end)
+       if (unlikely(*p + sizeof(*v) > end))
                return -EINVAL;
        *v = le32_to_cpu(*(__u32*)p);
        p += sizeof(*v);
        return 0;
 }
 static __inline__ int ceph_decode_16(void **p, void *end, __u16 *v) {
-       if (*p + sizeof(*v) > end)
+       if (unlikely(*p + sizeof(*v) > end))
                return -EINVAL;
        *v = le16_to_cpu(*(__u16*)p);
        p += sizeof(*v);
        return 0;
 }
 static __inline__ int ceph_decode_copy(void **p, void *end, void *v, int len) {
-       if (*p + len > end
+       if (unlikely(*p + len > end)
                return -EINVAL;
        memcpy(v, *p, len);
        *p += len;
@@ -159,7 +159,7 @@ static __inline__ int ceph_decode_addr(void **p, void *end, struct ceph_entity_a
 }
 
 static __inline__ int ceph_decode_name(void **p, void *end, struct ceph_entity_name *v) {
-       if (*p + sizeof(*v) > end)
+       if (unlikely(*p + sizeof(*v) > end))
                return -EINVAL;
        v->type = le32_to_cpu(*(__u32*)p);
        p += sizeof(__u32);
@@ -229,6 +229,7 @@ static __inline__ int ceph_encode_filepath(void **p, void *end, ceph_ino_t ino,
        ceph_encode_32(p, end, len);
        memcpy(*p, path, len);
        *p += len;
+       return 0;
 }
 
 
index 0fc839dfb0bc5462f6dffc12509fb169d7f6a4b3..83d77a97ed1eca52de623c4a8f7de1b964784a7e 100644 (file)
@@ -53,9 +53,9 @@ class CInode;
 struct DirStat {
   // mds distribution hints
   frag_t frag;
-  int auth;
-  set<int> dist;
-  bool is_rep;
+  __s32 auth;
+  set<__s32> dist;
+  __u8 is_rep;
   
   DirStat() {}
   DirStat(bufferlist::iterator& p) {
@@ -65,15 +65,18 @@ struct DirStat {
   void _decode(bufferlist::iterator& p) {
     ::_decode_simple(frag, p);
     ::_decode_simple(auth, p);
-    ::_decode_simple(dist, p);
     ::_decode_simple(is_rep, p);
+    ::_decode_simple(dist, p);
   }
 
   static void _encode(bufferlist& bl, CDir *dir, int whoami) {
+    /*
+     * note: encoding matches struct ceph_client_reply_dirfrag
+     */
     frag_t frag = dir->get_frag();
-    int auth;
-    set<int> dist;
-    bool is_rep;
+    __s32 auth;
+    set<__s32> dist;
+    __u8 is_rep;
     
     auth = dir->get_dir_auth().first;
     if (dir->is_auth()) 
@@ -82,8 +85,8 @@ struct DirStat {
 
     ::_encode_simple(frag, bl);
     ::_encode_simple(auth, bl);
-    ::_encode_simple(dist, bl);
     ::_encode_simple(is_rep, bl);
+    ::_encode_simple(dist, bl);
   }  
 };