Whamcloud - gitweb
LU-1201 checksum: add libcfs crypto hash
[fs/lustre-release.git] / lustre / ptlrpc / pack_generic.c
index be37b20..8dc8546 100644 (file)
@@ -1,6 +1,4 @@
-/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*-
- * vim:expandtab:shiftwidth=8:tabstop=8:
- *
+/*
  * GPL HEADER START
  *
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
@@ -28,9 +26,8 @@
 /*
  * Copyright (c) 2002, 2010, Oracle and/or its affiliates. All rights reserved.
  * Use is subject to license terms.
- */
-/*
- * Copyright (c) 2011 Whamcloud, Inc.
+ *
+ * Copyright (c) 2011, 2012, Whamcloud, Inc.
  */
 /*
  * This file is part of Lustre, http://www.lustre.org/
@@ -121,8 +118,17 @@ int lustre_msg_check_version(struct lustre_msg *msg, __u32 version)
 int lustre_msg_early_size()
 {
         static int size = 0;
-        if (!size)
-                size = lustre_msg_size(LUSTRE_MSG_MAGIC_V2, 1, NULL);
+       if (!size) {
+               /* Always reply old ptlrpc_body_v2 to keep interoprability
+                * with the old client (< 2.3) which doesn't have pb_jobid
+                * in the ptlrpc_body.
+                *
+                * XXX Remove this whenever we dorp interoprability with such
+                *     client.
+                */
+               __u32 pblen = sizeof(struct ptlrpc_body_v2);
+               size = lustre_msg_size(LUSTRE_MSG_MAGIC_V2, 1, &pblen);
+       }
         return size;
 }
 EXPORT_SYMBOL(lustre_msg_early_size);
@@ -156,7 +162,7 @@ int lustre_msg_size(__u32 magic, int count, __u32 *lens)
         }
 
         LASSERT(count > 0);
-        LASSERT(lens[MSG_PTLRPC_BODY_OFF] == sizeof(struct ptlrpc_body));
+       LASSERT(lens[MSG_PTLRPC_BODY_OFF] >= sizeof(struct ptlrpc_body_v2));
 
         switch (magic) {
         case LUSTRE_MSG_MAGIC_V2:
@@ -610,7 +616,7 @@ static inline int lustre_unpack_ptlrpc_body_v2(struct ptlrpc_request *req,
         struct ptlrpc_body *pb;
         struct lustre_msg_v2 *m = inout ? req->rq_reqmsg : req->rq_repmsg;
 
-        pb = lustre_msg_buf_v2(m, offset, sizeof(*pb));
+       pb = lustre_msg_buf_v2(m, offset, sizeof(struct ptlrpc_body_v2));
         if (!pb) {
                 CERROR("error unpacking ptlrpc body\n");
                 return -EFAULT;
@@ -784,7 +790,7 @@ static inline void *__lustre_swab_buf(struct lustre_msg *msg, int index,
 static inline struct ptlrpc_body *lustre_msg_ptlrpc_body(struct lustre_msg *msg)
 {
         return lustre_msg_buf_v2(msg, MSG_PTLRPC_BODY_OFF,
-                                 sizeof(struct ptlrpc_body));
+                                sizeof(struct ptlrpc_body_v2));
 }
 
 __u32 lustre_msghdr_get_flags(struct lustre_msg *msg)
@@ -1244,6 +1250,28 @@ __u32 lustre_msg_get_service_time(struct lustre_msg *msg)
         }
 }
 
+char *lustre_msg_get_jobid(struct lustre_msg *msg)
+{
+       switch (msg->lm_magic) {
+       case LUSTRE_MSG_MAGIC_V1:
+       case LUSTRE_MSG_MAGIC_V1_SWABBED:
+               return NULL;
+       case LUSTRE_MSG_MAGIC_V2: {
+               struct ptlrpc_body *pb =
+                       lustre_msg_buf_v2(msg, MSG_PTLRPC_BODY_OFF,
+                                         sizeof(struct ptlrpc_body));
+               if (!pb)
+                       return NULL;
+
+               return pb->pb_jobid;
+       }
+       default:
+               CERROR("incorrect message magic: %08x\n", msg->lm_magic);
+               return NULL;
+       }
+}
+EXPORT_SYMBOL(lustre_msg_get_jobid);
+
 __u32 lustre_msg_get_cksum(struct lustre_msg *msg)
 {
         switch (msg->lm_magic) {
@@ -1270,24 +1298,33 @@ __u32 lustre_msg_calc_cksum(struct lustre_msg *msg, int compat18)
 __u32 lustre_msg_calc_cksum(struct lustre_msg *msg)
 #endif
 {
-        switch (msg->lm_magic) {
-        case LUSTRE_MSG_MAGIC_V2: {
-                struct ptlrpc_body *pb = lustre_msg_ptlrpc_body(msg);
+       switch (msg->lm_magic) {
+       case LUSTRE_MSG_MAGIC_V2: {
+               struct ptlrpc_body *pb = lustre_msg_ptlrpc_body(msg);
 #if LUSTRE_VERSION_CODE < OBD_OCD_VERSION(2, 9, 0, 0)
-                __u32 len = compat18 ? ptlrpc_body_cksum_size_compat18 :
-                            lustre_msg_buflen(msg, MSG_PTLRPC_BODY_OFF);
-                LASSERTF(pb, "invalid msg %p: no ptlrpc body!\n", msg);
-                return crc32_le(~(__u32)0, (unsigned char *)pb, len);
+               __u32 crc;
+               unsigned int hsize = 4;
+               __u32 len = compat18 ? ptlrpc_body_cksum_size_compat18 :
+                           lustre_msg_buflen(msg, MSG_PTLRPC_BODY_OFF);
+               LASSERTF(pb, "invalid msg %p: no ptlrpc body!\n", msg);
+               cfs_crypto_hash_digest(CFS_HASH_ALG_CRC32, (unsigned char *)pb,
+                                      len, NULL, 0, (unsigned char *)&crc,
+                                      &hsize);
+               return crc;
 #else
 # warning "remove checksum compatibility support for b1_8"
-                return crc32_le(~(__u32)0, (unsigned char *)pb,
-                                lustre_msg_buflen(msg, MSG_PTLRPC_BODY_OFF));
+               __u32 crc;
+               unsigned int hsize = 4;
+               cfs_crypto_hash_digest(CFS_HASH_ALG_CRC32, (unsigned char *)pb,
+                                  lustre_msg_buflen(msg, MSG_PTLRPC_BODY_OFF),
+                                  NULL, 0, (unsigned char *)&crc, &hsize);
+               return crc;
 #endif
-        }
-        default:
-                CERROR("incorrect message magic: %08x\n", msg->lm_magic);
-                return 0;
-        }
+       }
+       default:
+               CERROR("incorrect message magic: %08x\n", msg->lm_magic);
+               return 0;
+       }
 }
 
 void lustre_msg_set_handle(struct lustre_msg *msg, struct lustre_handle *handle)
@@ -1453,6 +1490,33 @@ void lustre_msg_set_service_time(struct lustre_msg *msg, __u32 service_time)
         }
 }
 
+void lustre_msg_set_jobid(struct lustre_msg *msg, char *jobid)
+{
+       switch (msg->lm_magic) {
+       case LUSTRE_MSG_MAGIC_V1:
+               return;
+       case LUSTRE_MSG_MAGIC_V2: {
+               __u32 opc = lustre_msg_get_opc(msg);
+               struct ptlrpc_body *pb;
+
+               /* Don't set jobid for ldlm ast RPCs, they've been shrinked.
+                * See the comment in ptlrpc_request_pack(). */
+               if (!opc || opc == LDLM_BL_CALLBACK ||
+                   opc == LDLM_CP_CALLBACK || opc == LDLM_GL_CALLBACK)
+                       return;
+
+               pb = lustre_msg_buf_v2(msg, MSG_PTLRPC_BODY_OFF,
+                                      sizeof(struct ptlrpc_body));
+               LASSERTF(pb, "invalid msg %p: no ptlrpc body!\n", msg);
+               memcpy(pb->pb_jobid, jobid, JOBSTATS_JOBID_SIZE);
+               return;
+       }
+       default:
+               LASSERTF(0, "incorrect message magic: %08x\n", msg->lm_magic);
+       }
+}
+EXPORT_SYMBOL(lustre_msg_set_jobid);
+
 void lustre_msg_set_cksum(struct lustre_msg *msg, __u32 cksum)
 {
         switch (msg->lm_magic) {
@@ -1558,6 +1622,12 @@ void lustre_swab_ptlrpc_body(struct ptlrpc_body *b)
         __swab64s (&b->pb_pre_versions[2]);
         __swab64s (&b->pb_pre_versions[3]);
         CLASSERT(offsetof(typeof(*b), pb_padding) != 0);
+       /* While we need to maintain compatibility between
+        * clients and servers without ptlrpc_body_v2 (< 2.3)
+        * do not swab any fields beyond pb_jobid, as we are
+        * using this swab function for both ptlrpc_body
+        * and ptlrpc_body_v2. */
+       CLASSERT(offsetof(typeof(*b), pb_jobid) != 0);
 }
 
 void lustre_swab_connect(struct obd_connect_data *ocd)
@@ -1568,8 +1638,10 @@ void lustre_swab_connect(struct obd_connect_data *ocd)
         __swab64s(&ocd->ocd_ibits_known);
         __swab32s(&ocd->ocd_index);
         __swab32s(&ocd->ocd_brw_size);
-        __swab32s(&ocd->ocd_nllu);
-        __swab32s(&ocd->ocd_nllg);
+        /* ocd_blocksize and ocd_inodespace don't need to be swabbed because
+         * they are 8-byte values */
+        __swab16s(&ocd->ocd_grant_extent);
+        __swab32s(&ocd->ocd_unused);
         __swab64s(&ocd->ocd_transno);
         __swab32s(&ocd->ocd_group);
         __swab32s(&ocd->ocd_cksum_types);
@@ -1626,7 +1698,7 @@ void lustre_swab_obdo (struct obdo  *o)
         /* o_lcookie is swabbed elsewhere */
         __swab32s (&o->o_uid_h);
         __swab32s (&o->o_gid_h);
-        CLASSERT(offsetof(typeof(*o), o_padding_3) != 0);
+        __swab64s (&o->o_data_version);
         CLASSERT(offsetof(typeof(*o), o_padding_4) != 0);
         CLASSERT(offsetof(typeof(*o), o_padding_5) != 0);
         CLASSERT(offsetof(typeof(*o), o_padding_6) != 0);
@@ -1687,13 +1759,18 @@ void lustre_swab_generic_32s(__u32 *val)
         __swab32s(val);
 }
 
-void lustre_swab_ost_lvb(struct ost_lvb *lvb)
+void lustre_swab_lvb(union ldlm_wire_lvb *lvb)
 {
-        __swab64s(&lvb->lvb_size);
-        __swab64s(&lvb->lvb_mtime);
-        __swab64s(&lvb->lvb_atime);
-        __swab64s(&lvb->lvb_ctime);
-        __swab64s(&lvb->lvb_blocks);
+        /* The ldlm_wire_lvb union represents all the possible LVB types.
+         * Unfortunately, there is no way to know what member of the union we
+         * are dealing with at this point. Therefore, all LVB structures must
+         * have fields of the same types, although used for different purposes
+         */
+        __swab64s(&lvb->l_ost.lvb_size);
+        __swab64s(&lvb->l_ost.lvb_mtime);
+        __swab64s(&lvb->l_ost.lvb_atime);
+        __swab64s(&lvb->l_ost.lvb_ctime);
+        __swab64s(&lvb->l_ost.lvb_blocks);
 }
 
 void lustre_swab_mdt_body (struct mdt_body *b)
@@ -2264,11 +2341,13 @@ static inline int rep_ptlrpc_body_swabbed(struct ptlrpc_request *req)
         }
 }
 
-void _debug_req(struct ptlrpc_request *req, __u32 mask,
-                struct libcfs_debug_msg_data *data, const char *fmt, ... )
+void _debug_req(struct ptlrpc_request *req,
+                struct libcfs_debug_msg_data *msgdata,
+                const char *fmt, ... )
 {
         int req_ok = req->rq_reqmsg != NULL;
         int rep_ok = req->rq_repmsg != NULL;
+        lnet_nid_t nid = LNET_NID_ANY;
         va_list args;
 
         if (ptlrpc_req_need_swab(req)) {
@@ -2276,9 +2355,13 @@ void _debug_req(struct ptlrpc_request *req, __u32 mask,
                 rep_ok = rep_ok && rep_ptlrpc_body_swabbed(req);
         }
 
+        if (req->rq_import && req->rq_import->imp_connection)
+                nid = req->rq_import->imp_connection->c_peer.nid;
+        else if (req->rq_export && req->rq_export->exp_connection)
+                nid = req->rq_export->exp_connection->c_peer.nid;
+
         va_start(args, fmt);
-        libcfs_debug_vmsg2(data->msg_cdls, data->msg_subsys,mask,data->msg_file,
-                           data->msg_fn, data->msg_line, fmt, args,
+        libcfs_debug_vmsg2(msgdata, fmt, args,
                            " req@%p x"LPU64"/t"LPD64"("LPD64") o%d->%s@%s:%d/%d"
                            " lens %d/%d e %d to %d dl "CFS_TIME_T" ref %d "
                            "fl "REQ_FLAGS_FMT"/%x/%x rc %d/%d\n",
@@ -2290,11 +2373,7 @@ void _debug_req(struct ptlrpc_request *req, __u32 mask,
                                 req->rq_export ?
                                      req->rq_export->exp_client_uuid.uuid :
                                      "<?>",
-                           libcfs_nid2str(req->rq_import ?
-                                req->rq_import->imp_connection->c_peer.nid :
-                                req->rq_export ?
-                                     req->rq_export->exp_connection->c_peer.nid:
-                                     LNET_NID_ANY),
+                           libcfs_nid2str(nid),
                            req->rq_request_portal, req->rq_reply_portal,
                            req->rq_reqlen, req->rq_replen,
                            req->rq_early_count, req->rq_timedout,