Whamcloud - gitweb
LU-13127 ptlrpc: prefer crc32_le() over CryptoAPI
[fs/lustre-release.git] / lustre / ptlrpc / pack_generic.c
index 4d3879e..33b491c 100644 (file)
@@ -40,6 +40,8 @@
 
 #define DEBUG_SUBSYSTEM S_RPC
 
+#include <linux/crc32.h>
+
 #include <libcfs/libcfs.h>
 
 #include <llog_swab.h>
@@ -287,16 +289,15 @@ lustre_get_emerg_rs(struct ptlrpc_service_part *svcpt)
 
        /* See if we have anything in a pool, and wait if nothing */
        while (list_empty(&svcpt->scp_rep_idle)) {
-               struct l_wait_info      lwi;
                int                     rc;
 
                spin_unlock(&svcpt->scp_rep_lock);
                /* If we cannot get anything for some long time, we better
                 * bail out instead of waiting infinitely */
-               lwi = LWI_TIMEOUT(cfs_time_seconds(10), NULL, NULL);
-               rc = l_wait_event(svcpt->scp_rep_waitq,
-                                 !list_empty(&svcpt->scp_rep_idle), &lwi);
-               if (rc != 0)
+               rc = wait_event_idle_timeout(svcpt->scp_rep_waitq,
+                                            !list_empty(&svcpt->scp_rep_idle),
+                                            cfs_time_seconds(10));
+               if (rc <= 0)
                        goto out;
                spin_lock(&svcpt->scp_rep_lock);
        }
@@ -1286,11 +1287,12 @@ __u32 lustre_msg_get_magic(struct lustre_msg *msg)
        }
 }
 
-__u32 lustre_msg_get_timeout(struct lustre_msg *msg)
+timeout_t lustre_msg_get_timeout(struct lustre_msg *msg)
 {
        switch (msg->lm_magic) {
        case LUSTRE_MSG_MAGIC_V2: {
                struct ptlrpc_body *pb = lustre_msg_ptlrpc_body(msg);
+
                if (pb == NULL) {
                        CERROR("invalid msg %p: no ptlrpc body!\n", msg);
                        return 0;
@@ -1303,11 +1305,12 @@ __u32 lustre_msg_get_timeout(struct lustre_msg *msg)
        }
 }
 
-__u32 lustre_msg_get_service_time(struct lustre_msg *msg)
+timeout_t lustre_msg_get_service_timeout(struct lustre_msg *msg)
 {
        switch (msg->lm_magic) {
        case LUSTRE_MSG_MAGIC_V2: {
                struct ptlrpc_body *pb = lustre_msg_ptlrpc_body(msg);
+
                if (pb == NULL) {
                        CERROR("invalid msg %p: no ptlrpc body!\n", msg);
                        return 0;
@@ -1373,20 +1376,26 @@ __u64 lustre_msg_get_mbits(struct lustre_msg *msg)
        }
 }
 
-__u32 lustre_msg_calc_cksum(struct lustre_msg *msg)
+__u32 lustre_msg_calc_cksum(struct lustre_msg *msg, __u32 buf)
 {
        switch (msg->lm_magic) {
        case LUSTRE_MSG_MAGIC_V2: {
-               struct ptlrpc_body *pb = lustre_msg_ptlrpc_body(msg);
-               __u32 len = lustre_msg_buflen(msg, MSG_PTLRPC_BODY_OFF);
-
-               unsigned int hsize = 4;
+               struct ptlrpc_body *pb = lustre_msg_buf_v2(msg, buf, 0);
+               __u32 len = lustre_msg_buflen(msg, buf);
                __u32 crc;
 
                LASSERTF(pb != NULL, "invalid msg %p: no ptlrpc body!\n", msg);
+#if IS_ENABLED(CONFIG_CRC32)
+               /* about 10x faster than crypto_hash for small buffers */
+               crc = crc32_le(~(__u32)0, (unsigned char *)pb, len);
+#elif IS_ENABLED(CONFIG_CRYPTO_CRC32)
+               unsigned int hsize = 4;
                cfs_crypto_hash_digest(CFS_HASH_ALG_CRC32, (unsigned char *)pb,
                                       len, NULL, 0, (unsigned char *)&crc,
                                       &hsize);
+#else
+#error "need either CONFIG_CRC32 or CONFIG_CRYPTO_CRC32 enabled in the kernel"
+#endif
                return crc;
        }
        default:
@@ -1543,11 +1552,13 @@ void lustre_msg_set_conn_cnt(struct lustre_msg *msg, __u32 conn_cnt)
        }
 }
 
-void lustre_msg_set_timeout(struct lustre_msg *msg, __u32 timeout)
+void lustre_msg_set_timeout(struct lustre_msg *msg, timeout_t timeout)
 {
        switch (msg->lm_magic) {
        case LUSTRE_MSG_MAGIC_V2: {
                struct ptlrpc_body *pb = lustre_msg_ptlrpc_body(msg);
+
+               LASSERT(timeout >= 0);
                LASSERTF(pb != NULL, "invalid msg %p: no ptlrpc body!\n", msg);
                pb->pb_timeout = timeout;
                return;
@@ -1557,13 +1568,16 @@ void lustre_msg_set_timeout(struct lustre_msg *msg, __u32 timeout)
        }
 }
 
-void lustre_msg_set_service_time(struct lustre_msg *msg, __u32 service_time)
+void lustre_msg_set_service_timeout(struct lustre_msg *msg,
+                                   timeout_t service_timeout)
 {
        switch (msg->lm_magic) {
        case LUSTRE_MSG_MAGIC_V2: {
                struct ptlrpc_body *pb = lustre_msg_ptlrpc_body(msg);
+
+               LASSERT(service_timeout >= 0);
                LASSERTF(pb, "invalid msg %p: no ptlrpc body!\n", msg);
-               pb->pb_service_time = service_time;
+               pb->pb_service_time = service_timeout;
                return;
        }
        default:
@@ -1660,7 +1674,10 @@ int do_set_info_async(struct obd_import *imp,
        int rc;
 
        ENTRY;
-       req = ptlrpc_request_alloc(imp, &RQF_OBD_SET_INFO);
+
+       req = ptlrpc_request_alloc(imp, KEY_IS(KEY_CHANGELOG_CLEAR) ?
+                                               &RQF_MDT_SET_INFO :
+                                               &RQF_OBD_SET_INFO);
        if (req == NULL)
                RETURN(-ENOMEM);
 
@@ -1674,6 +1691,9 @@ int do_set_info_async(struct obd_import *imp,
                RETURN(rc);
        }
 
+       if (KEY_IS(KEY_CHANGELOG_CLEAR))
+               do_pack_body(req);
+
        tmp = req_capsule_client_get(&req->rq_pill, &RMF_SETINFO_KEY);
        memcpy(tmp, key, keylen);
        tmp = req_capsule_client_get(&req->rq_pill, &RMF_SETINFO_VAL);
@@ -1975,7 +1995,7 @@ void lustre_swab_mdt_body(struct mdt_body *b)
        __swab32s(&b->mbo_projid);
        __swab64s(&b->mbo_dom_size);
        __swab64s(&b->mbo_dom_blocks);
-       BUILD_BUG_ON(offsetof(typeof(*b), mbo_padding_8) == 0);
+       __swab64s(&b->mbo_btime);
        BUILD_BUG_ON(offsetof(typeof(*b), mbo_padding_9) == 0);
        BUILD_BUG_ON(offsetof(typeof(*b), mbo_padding_10) == 0);
 }
@@ -2061,14 +2081,19 @@ static void lustre_swab_obd_dqblk(struct obd_dqblk *b)
        BUILD_BUG_ON(offsetof(typeof(*b), dqb_padding) == 0);
 }
 
-void lustre_swab_obd_quotactl(struct obd_quotactl *q)
+int lustre_swab_obd_quotactl(struct obd_quotactl *q, __u32 len)
 {
+       if (unlikely(len <= sizeof(struct obd_quotactl)))
+               return -EOVERFLOW;
+
        __swab32s(&q->qc_cmd);
        __swab32s(&q->qc_type);
        __swab32s(&q->qc_id);
        __swab32s(&q->qc_stat);
        lustre_swab_obd_dqinfo(&q->qc_dqinfo);
        lustre_swab_obd_dqblk(&q->qc_dqblk);
+
+       return len;
 }
 
 void lustre_swab_fid2path(struct getinfo_fid2path *gf)
@@ -2099,14 +2124,25 @@ static void lustre_swab_fiemap_hdr(struct fiemap *fiemap)
        __swab32s(&fiemap->fm_reserved);
 }
 
-void lustre_swab_fiemap(struct fiemap *fiemap)
+int lustre_swab_fiemap(struct fiemap *fiemap, __u32 len)
 {
-       __u32 i;
+       __u32 i, size, count;
 
        lustre_swab_fiemap_hdr(fiemap);
 
-       for (i = 0; i < fiemap->fm_mapped_extents; i++)
+       size = fiemap_count_to_size(fiemap->fm_mapped_extents);
+       count = fiemap->fm_mapped_extents;
+       if (unlikely(size > len)) {
+               count = (len - sizeof(struct fiemap)) /
+                       sizeof(struct fiemap_extent);
+               fiemap->fm_mapped_extents = count;
+               size = -EOVERFLOW;
+       }
+       /* still swab extents as we cannot yet pass rc to callers */
+       for (i = 0; i < count; i++)
                lustre_swab_fiemap_extent(&fiemap->fm_extents[i]);
+
+       return size;
 }
 
 void lustre_swab_fiemap_info_key(struct ll_fiemap_info_key *fiemap_info)
@@ -2793,25 +2829,6 @@ void _debug_req(struct ptlrpc_request *req,
 }
 EXPORT_SYMBOL(_debug_req);
 
-void lustre_swab_lustre_capa(struct lustre_capa *c)
-{
-       lustre_swab_lu_fid(&c->lc_fid);
-       __swab64s(&c->lc_opc);
-       __swab64s(&c->lc_uid);
-       __swab64s(&c->lc_gid);
-       __swab32s(&c->lc_flags);
-       __swab32s(&c->lc_keyid);
-       __swab32s(&c->lc_timeout);
-       __swab32s(&c->lc_expiry);
-}
-
-void lustre_swab_lustre_capa_key(struct lustre_capa_key *k)
-{
-       __swab64s(&k->lk_seq);
-       __swab32s(&k->lk_keyid);
-       BUILD_BUG_ON(offsetof(typeof(*k), lk_padding) == 0);
-}
-
 void lustre_swab_hsm_user_state(struct hsm_user_state *state)
 {
        __swab32s(&state->hus_states);
@@ -2899,20 +2916,37 @@ void lustre_swab_object_update(struct object_update *ou)
        }
 }
 
-void lustre_swab_object_update_request(struct object_update_request *our)
+int lustre_swab_object_update_request(struct object_update_request *our,
+                                     __u32 len)
 {
-       size_t i;
+       __u32 i, size = 0;
+       struct object_update *ou;
+
        __swab32s(&our->ourq_magic);
        __swab16s(&our->ourq_count);
        __swab16s(&our->ourq_padding);
-       for (i = 0; i < our->ourq_count; i++) {
-               struct object_update *ou;
 
+       /* Don't need to calculate request size if len is 0. */
+       if (len > 0) {
+               size = sizeof(struct object_update_request);
+               for (i = 0; i < our->ourq_count; i++) {
+                       ou = object_update_request_get(our, i, NULL);
+                       if (ou == NULL)
+                               return -EPROTO;
+                       size += sizeof(struct object_update) +
+                               ou->ou_params_count *
+                               sizeof(struct object_update_param);
+               }
+               if (unlikely(size > len))
+                       return -EOVERFLOW;
+       }
+
+       for (i = 0; i < our->ourq_count; i++) {
                ou = object_update_request_get(our, i, NULL);
-               if (ou == NULL)
-                       return;
                lustre_swab_object_update(ou);
        }
+
+       return size;
 }
 
 void lustre_swab_object_update_result(struct object_update_result *our)
@@ -2922,22 +2956,30 @@ void lustre_swab_object_update_result(struct object_update_result *our)
        __swab16s(&our->our_padding);
 }
 
-void lustre_swab_object_update_reply(struct object_update_reply *our)
+int lustre_swab_object_update_reply(struct object_update_reply *our, __u32 len)
 {
-       size_t i;
+       __u32 i, size;
 
        __swab32s(&our->ourp_magic);
        __swab16s(&our->ourp_count);
        __swab16s(&our->ourp_padding);
+
+       size = sizeof(struct object_update_reply) + our->ourp_count *
+              (sizeof(__u16) + sizeof(struct object_update_result));
+       if (unlikely(size > len))
+               return -EOVERFLOW;
+
        for (i = 0; i < our->ourp_count; i++) {
                struct object_update_result *ourp;
 
                __swab16s(&our->ourp_lens[i]);
                ourp = object_update_result_get(our, i, NULL);
                if (ourp == NULL)
-                       return;
+                       return -EPROTO;
                lustre_swab_object_update_result(ourp);
        }
+
+       return size;
 }
 
 void lustre_swab_out_update_header(struct out_update_header *ouh)