Whamcloud - gitweb
LU-1201 checksum: add libcfs crypto hash
[fs/lustre-release.git] / lustre / ptlrpc / layout.c
index edd4f19..ed17822 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,6 +26,8 @@
 /*
  * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
  * Use is subject to license terms.
+ *
+ * Copyright (c) 2011, Whamcloud, Inc.
  */
 /*
  * This file is part of Lustre, http://www.lustre.org/
@@ -48,9 +48,6 @@
 
 #if !defined(__REQ_LAYOUT_USER__)
 
-#ifndef EXPORT_SYMTAB
-# define EXPORT_SYMTAB
-#endif
 #define DEBUG_SUBSYSTEM S_RPC
 
 #ifdef __KERNEL__
@@ -94,6 +91,16 @@ static const struct req_msg_field *mgs_set_info[] = {
         &RMF_MGS_SEND_PARAM
 };
 
+static const struct req_msg_field *mgs_config_read_client[] = {
+        &RMF_PTLRPC_BODY,
+        &RMF_MGS_CONFIG_BODY
+};
+
+static const struct req_msg_field *mgs_config_read_server[] = {
+        &RMF_PTLRPC_BODY,
+        &RMF_MGS_CONFIG_RES
+};
+
 static const struct req_msg_field *log_cancel_client[] = {
         &RMF_PTLRPC_BODY,
         &RMF_LOGCOOKIES
@@ -552,6 +559,7 @@ static struct req_format *req_formats[] = {
         &RQF_SEC_CTX,
         &RQF_MGS_TARGET_REG,
         &RQF_MGS_SET_INFO,
+        &RQF_MGS_CONFIG_READ,
         &RQF_SEQ_QUERY,
         &RQF_FLD_QUERY,
         &RQF_MDS_CONNECT,
@@ -687,6 +695,23 @@ struct req_msg_field RMF_MGS_SEND_PARAM =
                     NULL, NULL);
 EXPORT_SYMBOL(RMF_MGS_SEND_PARAM);
 
+struct req_msg_field RMF_MGS_CONFIG_BODY =
+        DEFINE_MSGF("mgs_config_read request", 0,
+                    sizeof(struct mgs_config_body),
+                    lustre_swab_mgs_config_body, NULL);
+EXPORT_SYMBOL(RMF_MGS_CONFIG_BODY);
+
+struct req_msg_field RMF_MGS_CONFIG_RES =
+        DEFINE_MSGF("mgs_config_read reply ", 0,
+                    sizeof(struct mgs_config_res),
+                    lustre_swab_mgs_config_res, NULL);
+EXPORT_SYMBOL(RMF_MGS_CONFIG_RES);
+
+struct req_msg_field RMF_U32 =
+        DEFINE_MSGF("generic u32", 0,
+                    sizeof(__u32), lustre_swab_generic_32s, NULL);
+EXPORT_SYMBOL(RMF_U32);
+
 struct req_msg_field RMF_SETINFO_VAL =
         DEFINE_MSGF("setinfo_val", 0, -1, NULL, NULL);
 EXPORT_SYMBOL(RMF_SETINFO_VAL);
@@ -818,7 +843,19 @@ EXPORT_SYMBOL(RMF_CONN);
 struct req_msg_field RMF_CONNECT_DATA =
         DEFINE_MSGF("cdata",
                     RMF_F_NO_SIZE_CHECK /* we allow extra space for interop */,
-                    sizeof(struct obd_connect_data), lustre_swab_connect, NULL);
+#if LUSTRE_VERSION_CODE > OBD_OCD_VERSION(2, 9, 0, 0)
+                    sizeof(struct obd_connect_data),
+#else
+/* For interoperability with 1.8 and 2.0 clients/servers.
+ * The RPC verification code allows larger RPC buffers, but not
+ * smaller buffers.  Until we no longer need to keep compatibility
+ * with older servers/clients we can only check that the buffer
+ * size is at least as large as obd_connect_data_v1.  That is not
+ * not in itself harmful, since the chance of just corrupting this
+ * field is low.  See JIRA LU-16 for details. */
+                    sizeof(struct obd_connect_data_v1),
+#endif
+                    lustre_swab_connect, NULL);
 EXPORT_SYMBOL(RMF_CONNECT_DATA);
 
 struct req_msg_field RMF_DLM_REQ =
@@ -838,7 +875,7 @@ struct req_msg_field RMF_LDLM_INTENT =
 EXPORT_SYMBOL(RMF_LDLM_INTENT);
 
 struct req_msg_field RMF_DLM_LVB =
-        DEFINE_MSGF("dlm_lvb", 0, sizeof(struct ost_lvb), lustre_swab_ost_lvb,
+        DEFINE_MSGF("dlm_lvb", 0, sizeof(union ldlm_wire_lvb), lustre_swab_lvb,
         NULL);
 EXPORT_SYMBOL(RMF_DLM_LVB);
 
@@ -967,6 +1004,11 @@ struct req_format RQF_MGS_SET_INFO =
                          mgs_set_info);
 EXPORT_SYMBOL(RQF_MGS_SET_INFO);
 
+struct req_format RQF_MGS_CONFIG_READ =
+        DEFINE_REQ_FMT0("MGS_CONFIG_READ", mgs_config_read_client,
+                         mgs_config_read_server);
+EXPORT_SYMBOL(RQF_MGS_CONFIG_READ);
+
 struct req_format RQF_SEQ_QUERY =
         DEFINE_REQ_FMT0("SEQ_QUERY", seq_query_client, seq_query_server);
 EXPORT_SYMBOL(RQF_SEQ_QUERY);
@@ -2040,5 +2082,67 @@ void req_capsule_shrink(struct req_capsule *pill,
 }
 EXPORT_SYMBOL(req_capsule_shrink);
 
+int req_capsule_server_grow(struct req_capsule *pill,
+                            const struct req_msg_field *field,
+                            unsigned int newlen)
+{
+        struct ptlrpc_reply_state *rs = pill->rc_req->rq_reply_state, *nrs;
+        char *from, *to;
+        int offset, len, rc;
+
+        LASSERT(pill->rc_fmt != NULL);
+        LASSERT(__req_format_is_sane(pill->rc_fmt));
+        LASSERT(req_capsule_has_field(pill, field, RCL_SERVER));
+        LASSERT(req_capsule_field_present(pill, field, RCL_SERVER));
+
+        len = req_capsule_get_size(pill, field, RCL_SERVER);
+        offset = __req_capsule_offset(pill, field, RCL_SERVER);
+        if (pill->rc_req->rq_repbuf_len >=
+            lustre_packed_msg_size(pill->rc_req->rq_repmsg) - len + newlen)
+                CERROR("Inplace repack might be done\n");
+
+        pill->rc_req->rq_reply_state = NULL;
+        req_capsule_set_size(pill, field, RCL_SERVER, newlen);
+        rc = req_capsule_server_pack(pill);
+        if (rc) {
+                /* put old rs back, the caller will decide what to do */
+                pill->rc_req->rq_reply_state = rs;
+                return rc;
+        }
+        nrs = pill->rc_req->rq_reply_state;
+        /* Now we need only buffers, copy first chunk */
+        to = lustre_msg_buf(nrs->rs_msg, 0, 0);
+        from = lustre_msg_buf(rs->rs_msg, 0, 0);
+        len = (char *)lustre_msg_buf(rs->rs_msg, offset, 0) - from;
+        memcpy(to, from, len);
+        /* check if we have tail and copy it too */
+        if (rs->rs_msg->lm_bufcount > offset + 1) {
+                to = lustre_msg_buf(nrs->rs_msg, offset + 1, 0);
+                from = lustre_msg_buf(rs->rs_msg, offset + 1, 0);
+                offset = rs->rs_msg->lm_bufcount - 1;
+                len = (char *)lustre_msg_buf(rs->rs_msg, offset, 0) +
+                      cfs_size_round(rs->rs_msg->lm_buflens[offset]) - from;
+                memcpy(to, from, len);
+        }
+        /* drop old reply if everything is fine */
+        if (rs->rs_difficult) {
+                /* copy rs data */
+                int i;
+
+                nrs->rs_difficult = 1;
+                nrs->rs_no_ack = rs->rs_no_ack;
+                for (i = 0; i < rs->rs_nlocks; i++) {
+                        nrs->rs_locks[i] = rs->rs_locks[i];
+                        nrs->rs_modes[i] = rs->rs_modes[i];
+                        nrs->rs_nlocks++;
+                }
+                rs->rs_nlocks = 0;
+                rs->rs_difficult = 0;
+                rs->rs_no_ack = 0;
+        }
+        ptlrpc_rs_decref(rs);
+        return 0;
+}
+EXPORT_SYMBOL(req_capsule_server_grow);
 /* __REQ_LAYOUT_USER__ */
 #endif