Whamcloud - gitweb
the last merge b_devel to b_cray
authornfshp <nfshp>
Tue, 8 Apr 2003 09:35:22 +0000 (09:35 +0000)
committernfshp <nfshp>
Tue, 8 Apr 2003 09:35:22 +0000 (09:35 +0000)
lustre/ptlrpc/pack_generic.c

index 12be831..8c5018f 100644 (file)
@@ -47,9 +47,11 @@ int lustre_pack_msg(int count, int *lens, char **bufs, int *len,
                 RETURN(-ENOMEM);
 
         m = *msg;
-        m->bufcount = HTON__u32(count);
+        m->magic = PTLRPC_MSG_MAGIC;
+        m->version = PTLRPC_MSG_VERSION;
+        m->bufcount = count;
         for (i = 0; i < count; i++)
-                m->buflens[i] = HTON__u32(lens[i]);
+                m->buflens[i] = lens[i];
 
         ptr = (char *)m + size_round(sizeof(*m) + count * sizeof(__u32));
         for (i = 0; i < count; i++) {
@@ -78,29 +80,71 @@ int lustre_msg_size(int count, int *lengths)
 
 int lustre_unpack_msg(struct lustre_msg *m, int len)
 {
-        int required_len, i;
+        int   flipped;
+        int   required_len;
+        int   i;
         ENTRY;
 
-        required_len = size_round(sizeof(*m));
-        if (len < required_len)
-                RETURN(-EINVAL);
+        /* We can provide a slightly better error log, if we check the
+         * message magic and version first.  In the future, struct
+         * lustre_msg may grow, and we'd like to log a version mismatch,
+         * rather than a short message.
+         *
+         */
+        required_len = MAX (offsetof (struct lustre_msg, version) + sizeof (m->version),
+                            offsetof (struct lustre_msg, magic) + sizeof (m->magic));
+        if (len < required_len) {
+                /* can't even look inside the message */
+                CERROR ("message length %d too small for magic/version check\n", len);
+                RETURN (-EINVAL);
+        }
+
+        flipped = (m->magic == __swab32 (PTLRPC_MSG_MAGIC));
+        if (flipped)
+                __swab32s (&m->version);
+        else if (m->magic != PTLRPC_MSG_MAGIC) {
+                CERROR("wrong lustre_msg magic %#08x\n", m->magic);
+                RETURN (-EINVAL);
+        }
+
+        if (m->version != PTLRPC_MSG_VERSION) {
+                CERROR("wrong lustre_msg version %#08x\n", m->version);
+                RETURN (-EINVAL);
+        }
 
-        m->opc = NTOH__u32(m->opc);
-        m->status = NTOH__u32(m->status);
-        m->type = NTOH__u32(m->type);
-        m->bufcount = NTOH__u32(m->bufcount);
-        m->last_xid = NTOH__u64(m->last_xid);
-        m->last_committed = NTOH__u64(m->last_committed);
+        /* Now we know the sender speaks my language (but possibly flipped)... */
+        required_len = size_round(sizeof(*m));
+        if (len < required_len) {
+                /* can't even look inside the message */
+                CERROR ("message length %d too small for lustre_msg\n", len);
+                RETURN (-EINVAL);
+        }
 
-        required_len = size_round(sizeof(*m) + m->bufcount * sizeof(__u32));
-        if (len < required_len)
+        if (flipped) {
+                __swab32s (&m->type);
+                __swab32s (&m->opc);
+                __swab64s (&m->last_xid);
+                __swab64s (&m->last_committed);
+                __swab64s (&m->transno);
+                __swab32s (&m->status);
+                __swab32s (&m->bufcount);
+                __swab32s (&m->flags);
+        }
+        
+        required_len = size_round (offsetof (struct lustre_msg, buflens[m->bufcount]));
+        if (len < required_len) {
+                /* didn't receive all the buffer lengths */
+                CERROR ("message length %d too small for %d buflens\n", 
+                        len, m->bufcount);
                 RETURN(-EINVAL);
+        }
 
         for (i = 0; i < m->bufcount; i++) {
-                m->buflens[i] = NTOH__u32(m->buflens[i]);
+                if (flipped)
+                        __swab32s (&m->buflens[i]);
                 required_len += size_round(m->buflens[i]);
         }
-
+        
         if (len < required_len) {
                 CERROR("len: %d, required_len %d\n", len, required_len);
                 CERROR("bufcount: %d\n", m->bufcount);
@@ -112,33 +156,384 @@ int lustre_unpack_msg(struct lustre_msg *m, int len)
         RETURN(0);
 }
 
-void *lustre_msg_buf(struct lustre_msg *m, int n)
+void *lustre_msg_buf(struct lustre_msg *m, int n, int min_size)
 {
-        int i, offset;
-
-        if (!m) {
-                CERROR("no message buffer!\n");
-                LBUG();
+        int i;
+        int offset;
+        int buflen;
+        int bufcount;
+        
+        LASSERT (m != NULL);
+        LASSERT (n >= 0);
+        
+        bufcount = m->bufcount;
+        if (n >= bufcount) {
+                CERROR("msg %p buffer[%d] not present (count %d)\n",
+                       m, n, bufcount);
                 return NULL;
         }
 
-        if (n < 0 || n >= m->bufcount) {
-                CERROR("referencing bad sub buffer in %p (want %d, count "
-                       "%d)!\n", m, n, m->bufcount);
-                LBUG();
+        buflen = m->buflens[n];
+        if (buflen == 0) {
+                CERROR("msg %p buffer[%d] is zero length\n", m, n);
                 return NULL;
         }
 
-        if (m->buflens[n] == 0) {
-                CERROR("zero-length buffer requested for buffer %d in %p\n",
-                       n, m);
+        if (buflen < min_size) {
+                CERROR("msg %p buffer[%d] size %d too small (required %d)\n",
+                        m, n, buflen, min_size);
                 return NULL;
         }
-
-        offset = size_round(sizeof(*m) + m->bufcount * sizeof(__u32));
-
+        
+        offset = size_round (offsetof (struct lustre_msg, buflens[bufcount]));
         for (i = 0; i < n; i++)
                 offset += size_round(m->buflens[i]);
 
         return (char *)m + offset;
 }
+
+char *lustre_msg_string (struct lustre_msg *m, int index, int max_len)
+{
+        /* max_len == 0 means the string should fill the buffer */
+        char *str = lustre_msg_buf (m, index, 0);
+        int   slen;
+        int   blen;
+        
+        if (str == NULL) {
+                CERROR ("can't unpack string in msg %p buffer[%d]\n", m, index);
+                return (NULL);
+        }
+
+        blen = m->buflens[index];
+        slen = strnlen (str, blen);
+        
+        if (slen == blen) {                     /* not NULL terminated */
+                CERROR ("can't unpack non-NULL terminated string in "
+                        "msg %p buffer[%d] len %d\n", m, index, blen);
+                return (NULL);
+        }
+        
+        if (max_len == 0) {
+                if (slen != blen - 1) {
+                        CERROR ("can't unpack short string in msg %p "
+                                "buffer[%d] len %d: strlen %d\n",
+                                m, index, blen, slen);
+                        return (NULL);
+                }
+        } else if (slen > max_len) {
+                CERROR ("can't unpack oversized string in msg %p "
+                        "buffer[%d] len %d strlen %d: max %d expected\n", 
+                        m, index, blen, slen, max_len);
+                return (NULL);
+        }
+
+        return (str);
+}
+
+/* Wrap up the normal fixed length case */
+void *lustre_swab_reqbuf (struct ptlrpc_request *req, int index, int min_size, void *swabber)
+{
+        void *ptr;
+        
+        LASSERT_REQSWAB (req, index);
+
+        ptr = lustre_msg_buf (req->rq_reqmsg, index, min_size);
+        if (ptr == NULL)
+                return (NULL);
+        
+        if (swabber != NULL &&
+            lustre_msg_swabbed (req->rq_reqmsg))
+                ((void (*)(void *))swabber)(ptr);
+        
+        return (ptr);
+}
+
+/* Wrap up the normal fixed length case */
+void *lustre_swab_repbuf (struct ptlrpc_request *req, int index, int min_size, void *swabber)
+{
+        void *ptr;
+        
+        LASSERT_REPSWAB (req, index);
+
+        ptr = lustre_msg_buf (req->rq_repmsg, index, min_size);
+        if (ptr == NULL)
+                return (NULL);
+        
+        if (swabber != NULL &&
+            lustre_msg_swabbed (req->rq_repmsg))
+                ((void (*)(void *))swabber)(ptr);
+        
+        return (ptr);
+}
+
+/* byte flipping routines for all wire types declared in
+ * lustre_idl.h implemented here.
+ */
+
+void lustre_swab_obdo (struct obdo  *o)
+{
+        __swab64s (&o->o_id);
+        __swab64s (&o->o_gr);
+        __swab64s (&o->o_atime);
+        __swab64s (&o->o_mtime);
+        __swab64s (&o->o_ctime);
+        __swab64s (&o->o_size);
+        __swab64s (&o->o_blocks);
+        __swab64s (&o->o_rdev);
+        __swab32s (&o->o_blksize);
+        __swab32s (&o->o_mode);
+        __swab32s (&o->o_uid);
+        __swab32s (&o->o_gid);
+        __swab32s (&o->o_flags);
+        __swab32s (&o->o_nlink);
+        __swab32s (&o->o_generation);
+        __swab32s (&o->o_valid);
+        __swab32s (&o->o_obdflags);
+        __swab32s (&o->o_easize);
+        /* o_inline is opaque */
+}
+
+void lustre_swab_obd_statfs (struct obd_statfs *os)
+{
+        __swab64s (&os->os_type);
+        __swab64s (&os->os_blocks);
+        __swab64s (&os->os_bfree);
+        __swab64s (&os->os_bavail);
+        __swab64s (&os->os_ffree);
+        /* no need to swap os_fsid */
+        __swab32s (&os->os_bsize);
+        __swab32s (&os->os_namelen);
+        /* no need to swap os_spare */
+}
+
+void lustre_swab_obd_ioobj (struct obd_ioobj *ioo)
+{
+        __swab64s (&ioo->ioo_id);
+        __swab64s (&ioo->ioo_gr);
+        __swab32s (&ioo->ioo_type);
+        __swab32s (&ioo->ioo_bufcnt);
+}
+
+void lustre_swab_niobuf_remote (struct niobuf_remote *nbr)
+{
+        __swab64s (&nbr->offset);
+        __swab32s (&nbr->len);
+        __swab32s (&nbr->xid);
+        __swab32s (&nbr->flags);
+}
+
+void lustre_swab_ost_body (struct ost_body *b)
+{
+        lustre_swab_obdo (&b->oa);
+}
+
+void lustre_swab_ll_fid (struct ll_fid *fid) 
+{
+        __swab64s (&fid->id);
+        __swab32s (&fid->generation);
+        __swab32s (&fid->f_type);
+}
+
+void lustre_swab_mds_status_req (struct mds_status_req *r)
+{
+        __swab32s (&r->flags);
+        __swab32s (&r->repbuf);
+}
+
+void lustre_swab_mds_fileh_body (struct mds_fileh_body *f)
+{
+        lustre_swab_ll_fid (&f->f_fid);
+}
+
+void lustre_swab_mds_body (struct mds_body *b)
+{
+        lustre_swab_ll_fid (&b->fid1);
+        lustre_swab_ll_fid (&b->fid2);
+        /* handle is opaque */
+        __swab64s (&b->size);
+        __swab64s (&b->blocks);
+        __swab32s (&b->ino);
+        __swab32s (&b->valid);
+        __swab32s (&b->fsuid);
+        __swab32s (&b->fsgid);
+        __swab32s (&b->capability);
+        __swab32s (&b->mode);
+        __swab32s (&b->uid);
+        __swab32s (&b->gid);
+        __swab32s (&b->mtime);
+        __swab32s (&b->ctime);
+        __swab32s (&b->atime);
+        __swab32s (&b->flags);
+        __swab32s (&b->rdev);
+        __swab32s (&b->nlink);
+        __swab32s (&b->generation);
+        __swab32s (&b->suppgid);
+        __swab32s (&b->eadatasize);
+}
+
+void lustre_swab_mds_rec_setattr (struct mds_rec_setattr *sa)
+{
+        __swab32s (&sa->sa_opcode);
+        __swab32s (&sa->sa_fsuid);
+        __swab32s (&sa->sa_fsgid);
+        __swab32s (&sa->sa_cap);
+        __swab32s (&sa->sa_reserved);
+        __swab32s (&sa->sa_valid);
+        lustre_swab_ll_fid (&sa->sa_fid);
+        __swab32s (&sa->sa_mode);
+        __swab32s (&sa->sa_uid);
+        __swab32s (&sa->sa_gid);
+        __swab32s (&sa->sa_attr_flags);
+        __swab64s (&sa->sa_size);
+        __swab64s (&sa->sa_atime);
+        __swab64s (&sa->sa_mtime);
+        __swab64s (&sa->sa_ctime);
+        __swab32s (&sa->sa_suppgid);
+}
+
+void lustre_swab_mds_rec_create (struct mds_rec_create *cr)
+{
+        __swab32s (&cr->cr_opcode);
+        __swab32s (&cr->cr_fsuid);
+        __swab32s (&cr->cr_fsgid);
+        __swab32s (&cr->cr_cap);
+        __swab32s (&cr->cr_flags); /* for use with open */
+        __swab32s (&cr->cr_mode);
+        lustre_swab_ll_fid (&cr->cr_fid);
+        lustre_swab_ll_fid (&cr->cr_replayfid);
+        __swab32s (&cr->cr_uid);
+        __swab32s (&cr->cr_gid);
+        __swab64s (&cr->cr_time);
+        __swab64s (&cr->cr_rdev);
+        __swab32s (&cr->cr_suppgid);
+}
+
+void lustre_swab_mds_rec_link (struct mds_rec_link *lk)
+{
+        __swab32s (&lk->lk_opcode);
+        __swab32s (&lk->lk_fsuid);
+        __swab32s (&lk->lk_fsgid);
+        __swab32s (&lk->lk_cap);
+        __swab32s (&lk->lk_suppgid);
+        lustre_swab_ll_fid (&lk->lk_fid1);
+        lustre_swab_ll_fid (&lk->lk_fid2);
+}
+
+void lustre_swab_mds_rec_unlink (struct mds_rec_unlink *ul)
+{
+        __swab32s (&ul->ul_opcode);
+        __swab32s (&ul->ul_fsuid);
+        __swab32s (&ul->ul_fsgid);
+        __swab32s (&ul->ul_cap);
+        __swab32s (&ul->ul_reserved);
+        __swab32s (&ul->ul_mode);
+        __swab32s (&ul->ul_suppgid);
+        lustre_swab_ll_fid (&ul->ul_fid1);
+        lustre_swab_ll_fid (&ul->ul_fid2);
+}
+
+void lustre_swab_mdx_rec_rename (struct mds_rec_rename *rn)
+{
+        __swab32s (&rn->rn_opcode);
+        __swab32s (&rn->rn_fsuid);
+        __swab32s (&rn->rn_fsgid);
+        __swab32s (&rn->rn_cap);
+        __swab32s (&rn->rn_suppgid1);
+        __swab32s (&rn->rn_suppgid2);
+        lustre_swab_ll_fid (&rn->rn_fid1);
+        lustre_swab_ll_fid (&rn->rn_fid2);
+}
+
+void lustre_swab_lov_desc (struct lov_desc *ld)
+{
+        __swab32s (&ld->ld_tgt_count);
+        __swab32s (&ld->ld_active_tgt_count);
+        __swab32s (&ld->ld_default_stripe_count);
+        __swab64s (&ld->ld_default_stripe_size);
+        __swab64s (&ld->ld_default_stripe_offset);
+        __swab32s (&ld->ld_pattern);
+        /* uuid endian insensitive */
+}
+
+void lustre_swab_ldlm_res_id (struct ldlm_res_id *id)
+{
+        int  i;
+        
+        for (i = 0; i < RES_NAME_SIZE; i++)
+                __swab64s (&id->name[i]);
+}
+
+void lustre_swab_ldlm_extent (struct ldlm_extent *e)
+{
+        __swab64s (&e->start);
+        __swab64s (&e->end);
+}
+
+void lustre_swab_ldlm_intent (struct ldlm_intent *i)
+{
+        __swab64s (&i->opc);
+}
+
+void lustre_swab_ldlm_resource_desc (struct ldlm_resource_desc *r)
+{
+        int   i;
+        
+        __swab32s (&r->lr_type);
+        lustre_swab_ldlm_res_id (&r->lr_name);
+        for (i = 0; i < RES_VERSION_SIZE; i++)
+                __swab32s (&r->lr_version[i]);
+}
+
+void lustre_swab_ldlm_lock_desc (struct ldlm_lock_desc *l)
+{
+        int   i;
+        
+        lustre_swab_ldlm_resource_desc (&l->l_resource);
+        __swab32s (&l->l_req_mode);
+        __swab32s (&l->l_granted_mode);
+        lustre_swab_ldlm_extent (&l->l_extent);
+        for (i = 0; i < RES_VERSION_SIZE; i++)
+                __swab32s (&l->l_version[i]);
+}
+
+void lustre_swab_ldlm_request (struct ldlm_request *rq)
+{
+        __swab32s (&rq->lock_flags);
+        lustre_swab_ldlm_lock_desc (&rq->lock_desc);
+        /* lock_handle1 opaque */
+        /* lock_handle2 opaque */
+}
+
+void lustre_swab_ldlm_reply (struct ldlm_reply *r)
+{
+        __swab32s (&r->lock_flags);
+        __swab32s (&r->lock_mode);
+        lustre_swab_ldlm_res_id (&r->lock_resource_name);
+        /* lock_handle opaque */
+        lustre_swab_ldlm_extent (&r->lock_extent);
+        __swab64s (&r->lock_policy_res1);
+        __swab64s (&r->lock_policy_res2);
+}
+
+void lustre_swab_ptlbd_op (struct ptlbd_op *op)
+{
+        __swab16s (&op->op_cmd);
+        __swab16s (&op->op_lun);
+        __swab16s (&op->op_niob_cnt);
+        /* ignore op__padding */
+        __swab32s (&op->op_block_cnt);
+}
+
+void lustre_swab_ptlbd_niob (struct ptlbd_niob *n)
+{
+        __swab64s (&n->n_xid);
+        __swab64s (&n->n_block_nr);
+        __swab32s (&n->n_offset);
+        __swab32s (&n->n_length);
+}
+
+void lustre_swab_ptlbd_rsp (struct ptlbd_rsp *r)
+{
+        __swab16s (&r->r_status);
+        __swab16s (&r->r_error_cnt);
+}