Introduce "OBD_CONNECT_FULL20" to distinguish 1.8 client from 2.0 one for different checksum policy:
1) for 1.8 client, use fixed first 88 bytes of ptlrpc_body
2) for 2.0 client, use lm_buflens
i=andreas.dilger
i=robert.read
OBD_CONNECT_IBITS |
OBD_CONNECT_MDS_MDS |
OBD_CONNECT_FID |
- OBD_CONNECT_AT;
+ OBD_CONNECT_AT |
+ OBD_CONNECT_FULL20;
rc = obd_connect(env, &desc->cl_exp, mdc, &mdc->obd_uuid, ocd, NULL);
OBD_FREE_PTR(ocd);
if (rc) {
/* flags for lm_flags */
#define MSGHDR_AT_SUPPORT 0x1
+#define MSGHDR_CKSUM_INCOMPAT18 0x2
#define lustre_msg lustre_msg_v2
/* we depend on this structure to be 8-byte aligned */
#define OBD_CONNECT_LOV_V3 0x100000000ULL /*client supports LOV v3 EA */
#define OBD_CONNECT_GRANT_SHRINK 0x200000000ULL /* support grant shrink */
#define OBD_CONNECT_SKIP_ORPHAN 0x400000000ULL /* don't reuse orphan objids */
+#define OBD_CONNECT_FULL20 0x800000000ULL /* it is 2.0 client */
/* also update obd_connect_names[] for lprocfs_rd_connect_flags()
* and lustre/utils/wirecheck.c */
OBD_CONNECT_MDS_CAPA | OBD_CONNECT_OSS_CAPA | \
OBD_CONNECT_MDS_MDS | OBD_CONNECT_FID | \
LRU_RESIZE_CONNECT_FLAG | OBD_CONNECT_VBR | \
- OBD_CONNECT_LOV_V3 | OBD_CONNECT_SOM)
+ OBD_CONNECT_LOV_V3 | OBD_CONNECT_SOM | \
+ OBD_CONNECT_FULL20)
#define OST_CONNECT_SUPPORTED (OBD_CONNECT_SRVLOCK | OBD_CONNECT_GRANT | \
OBD_CONNECT_REQPORTAL | OBD_CONNECT_VERSION | \
OBD_CONNECT_TRUNCLOCK | OBD_CONNECT_INDEX | \
OBD_CONNECT_OSS_CAPA | OBD_CONNECT_RMT_CLIENT | \
OBD_CONNECT_RMT_CLIENT_FORCE | OBD_CONNECT_VBR | \
OBD_CONNECT_MDS | OBD_CONNECT_SKIP_ORPHAN | \
- OBD_CONNECT_GRANT_SHRINK)
+ OBD_CONNECT_GRANT_SHRINK | OBD_CONNECT_FULL20)
#define ECHO_CONNECT_SUPPORTED (0)
-#define MGS_CONNECT_SUPPORTED (OBD_CONNECT_VERSION | OBD_CONNECT_AT)
+#define MGS_CONNECT_SUPPORTED (OBD_CONNECT_VERSION | OBD_CONNECT_AT | \
+ OBD_CONNECT_FULL20)
#define OBD_OCD_VERSION(major,minor,patch,fix) (((major)<<24) + ((minor)<<16) +\
((patch)<<8) + (fix))
#include <lustre_req_layout.h>
#include <obd_support.h>
+#include <lustre_ver.h>
/* MD flags we _always_ use */
#define PTLRPC_MD_OPTIONS 0
__u32 lustre_msg_get_timeout(struct lustre_msg *msg);
__u32 lustre_msg_get_service_time(struct lustre_msg *msg);
__u32 lustre_msg_get_cksum(struct lustre_msg *msg);
+#if LUSTRE_VERSION_CODE < OBD_OCD_VERSION(2, 9, 0, 0)
+__u32 lustre_msg_calc_cksum(struct lustre_msg *msg, int compat18);
+#else
+# warning "remove checksum compatibility support for b1_8"
__u32 lustre_msg_calc_cksum(struct lustre_msg *msg);
+#endif
void lustre_msg_set_handle(struct lustre_msg *msg,struct lustre_handle *handle);
void lustre_msg_set_type(struct lustre_msg *msg, __u32 type);
void lustre_msg_set_opc(struct lustre_msg *msg, __u32 opc);
else
revimp->imp_msghdr_flags &= ~MSGHDR_AT_SUPPORT;
+ if ((export->exp_connect_flags & OBD_CONNECT_FULL20) &&
+ (revimp->imp_msg_magic != LUSTRE_MSG_MAGIC_V1))
+ revimp->imp_msghdr_flags |= MSGHDR_CKSUM_INCOMPAT18;
+ else
+ revimp->imp_msghdr_flags &= ~MSGHDR_CKSUM_INCOMPAT18;
+
rc = sptlrpc_import_sec_adapt(revimp, req->rq_svc_ctx, &req->rq_flvr);
if (rc) {
CERROR("Failed to get sec for reverse import: %d\n", rc);
GOTO(out_cleanup, rc = -ENOMEM);
ocd->ocd_connect_flags = OBD_CONNECT_VERSION | OBD_CONNECT_FID |
- OBD_CONNECT_AT | OBD_CONNECT_VBR;
+ OBD_CONNECT_AT | OBD_CONNECT_VBR |
+ OBD_CONNECT_FULL20;
#ifdef LIBLUSTRE_POSIX_ACL
ocd->ocd_connect_flags |= OBD_CONNECT_ACL;
#endif
ocd.ocd_connect_flags = OBD_CONNECT_IBITS | OBD_CONNECT_VERSION |
OBD_CONNECT_FID | OBD_CONNECT_AT |
- OBD_CONNECT_VBR | OBD_CONNECT_SOM;
+ OBD_CONNECT_VBR | OBD_CONNECT_SOM |
+ OBD_CONNECT_FULL20;
#ifdef LIBLUSTRE_POSIX_ACL
ocd.ocd_connect_flags |= OBD_CONNECT_ACL;
#endif
ocd.ocd_connect_flags = OBD_CONNECT_SRVLOCK | OBD_CONNECT_REQPORTAL |
OBD_CONNECT_VERSION | OBD_CONNECT_TRUNCLOCK |
OBD_CONNECT_FID | OBD_CONNECT_AT |
- OBD_CONNECT_SOM;
+ OBD_CONNECT_SOM | OBD_CONNECT_FULL20;
ocd.ocd_version = LUSTRE_VERSION_CODE;
err = obd_connect(NULL, &sbi->ll_dt_exp, obd, &sbi->ll_sb_uuid, &ocd, NULL);
OBD_CONNECT_OSS_CAPA | OBD_CONNECT_CANCELSET|
OBD_CONNECT_FID | OBD_CONNECT_AT |
OBD_CONNECT_LOV_V3 | OBD_CONNECT_RMT_CLIENT |
- OBD_CONNECT_VBR | OBD_CONNECT_SOM;
+ OBD_CONNECT_VBR | OBD_CONNECT_SOM |
+ OBD_CONNECT_FULL20;
#ifdef HAVE_LRU_RESIZE_SUPPORT
if (sbi->ll_flags & LL_SBI_LRU_RESIZE)
OBD_CONNECT_SRVLOCK | OBD_CONNECT_TRUNCLOCK|
OBD_CONNECT_AT | OBD_CONNECT_RMT_CLIENT |
OBD_CONNECT_OSS_CAPA | OBD_CONNECT_VBR|
- OBD_CONNECT_SOM;
+ OBD_CONNECT_SOM | OBD_CONNECT_FULL20;
if (!OBD_FAIL_CHECK(OBD_FAIL_OSC_CONNECT_CKSUM)) {
/* OBD_CONNECT_CKSUM should always be set, even if checksums are
OBD_CONNECT_BRW_SIZE | OBD_CONNECT_CKSUM |
OBD_CONNECT_CHANGE_QS | OBD_CONNECT_AT |
OBD_CONNECT_MDS | OBD_CONNECT_SKIP_ORPHAN |
- OBD_CONNECT_SOM;
+ OBD_CONNECT_SOM | OBD_CONNECT_FULL20;
#ifdef HAVE_LRU_RESIZE_SUPPORT
data->ocd_connect_flags |= OBD_CONNECT_LRU_RESIZE;
#endif
if (data == NULL)
GOTO(out, rc = -ENOMEM);
data->ocd_connect_flags = OBD_CONNECT_VERSION | OBD_CONNECT_FID |
- OBD_CONNECT_AT;
+ OBD_CONNECT_AT | OBD_CONNECT_FULL20;
data->ocd_version = LUSTRE_VERSION_CODE;
rc = obd_connect(NULL, &exp, obd, &(obd->obd_uuid), data, NULL);
OBD_FREE_PTR(data);
* the server is updated on-the-fly we will get the new features. */
imp->imp_connect_data.ocd_connect_flags = imp->imp_connect_flags_orig;
imp->imp_msghdr_flags &= ~MSGHDR_AT_SUPPORT;
+ imp->imp_msghdr_flags &= ~MSGHDR_CKSUM_INCOMPAT18;
rc = obd_reconnect(NULL, imp->imp_obd->obd_self_export, obd,
&obd->obd_uuid, &imp->imp_connect_data, NULL);
else
imp->imp_msghdr_flags &= ~MSGHDR_AT_SUPPORT;
+ if ((ocd->ocd_connect_flags & OBD_CONNECT_FULL20) &&
+ (imp->imp_msg_magic == LUSTRE_MSG_MAGIC_V2))
+ imp->imp_msghdr_flags |= MSGHDR_CKSUM_INCOMPAT18;
+ else
+ imp->imp_msghdr_flags &= ~MSGHDR_CKSUM_INCOMPAT18;
+
LASSERT((cli->cl_max_pages_per_rpc <= PTLRPC_MAX_BRW_PAGES) &&
(cli->cl_max_pages_per_rpc > 0));
}
}
}
+#if LUSTRE_VERSION_CODE < OBD_OCD_VERSION(2, 9, 0, 0)
+/*
+ * In 1.6 and 1.8 the checksum was computed only on struct ptlrpc_body as
+ * it was in 1.6 (88 bytes, smaller than the full size in 1.8). It makes
+ * more sense to compute the checksum on the full ptlrpc_body, regardless
+ * of what size it is, but in order to keep interoperability with 1.8 we
+ * can optionally also checksum only the first 88 bytes (caller decides). */
+# define ptlrpc_body_cksum_size_compat18 88
+
+__u32 lustre_msg_calc_cksum(struct lustre_msg *msg, int compat18)
+#else
+# warning "remove checksum compatibility support for b1_8"
__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);
+#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, sizeof(*pb));
+ return crc32_le(~(__u32)0, (unsigned char *)pb, len);
+#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));
+#endif
}
default:
CERROR("incorrect message magic: %08x\n", msg->lm_magic);
early_req->rq_repdata = (struct lustre_msg *) early_buf;
early_req->rq_repdata_len = early_size;
early_req->rq_early = 1;
+ early_req->rq_reqmsg = req->rq_reqmsg;
rc = do_cli_unwrap_reply(early_req);
if (rc) {
if (req->rq_early) {
cksums = lustre_msg_get_cksum(req->rq_repdata);
+#if LUSTRE_VERSION_CODE < OBD_OCD_VERSION(2, 9, 0, 0)
+ if (lustre_msghdr_get_flags(req->rq_reqmsg) &
+ MSGHDR_CKSUM_INCOMPAT18)
+ cksumc = lustre_msg_calc_cksum(req->rq_repmsg, 0);
+ else
+ cksumc = lustre_msg_calc_cksum(req->rq_repmsg, 1);
+#else
+# warning "remove checksum compatibility support for b1_8"
cksumc = lustre_msg_calc_cksum(req->rq_repmsg);
+#endif
if (cksumc != cksums) {
CWARN("early reply checksum mismatch: %08x != %08x\n",
cksumc, cksums);
else
req->rq_reply_off = 0;
} else {
- lustre_msg_set_cksum(rs->rs_repbuf,
- lustre_msg_calc_cksum(rs->rs_repbuf));
+ __u32 cksum;
+
+#if LUSTRE_VERSION_CODE < OBD_OCD_VERSION(2, 9, 0, 0)
+ if (lustre_msghdr_get_flags(req->rq_reqmsg) &
+ MSGHDR_CKSUM_INCOMPAT18)
+ cksum = lustre_msg_calc_cksum(rs->rs_repbuf, 0);
+ else
+ cksum = lustre_msg_calc_cksum(rs->rs_repbuf, 1);
+#else
+# warning "remove checksum compatibility support for b1_8"
+ cksum = lustre_msg_calc_cksum(rs->rs_repbuf);
+#endif
+ lustre_msg_set_cksum(rs->rs_repbuf, cksum);
req->rq_reply_off = 0;
}
CLASSERT(OBD_CONNECT_LRU_RESIZE == 0x2000000ULL);
CLASSERT(OBD_CONNECT_VBR == 0x80000000ULL);
CLASSERT(OBD_CONNECT_SKIP_ORPHAN == 0x400000000ULL);
+ CLASSERT(OBD_CONNECT_FULL20 == 0x800000000ULL);
/* Checks for struct obdo */
LASSERTF((int)sizeof(struct obdo) == 208, " found %lld\n",
CHECK_CDEFINE(OBD_CONNECT_LRU_RESIZE);
CHECK_CDEFINE(OBD_CONNECT_VBR);
CHECK_CDEFINE(OBD_CONNECT_SKIP_ORPHAN);
+ CHECK_CDEFINE(OBD_CONNECT_FULL20);
}
static void
CLASSERT(OBD_CONNECT_LRU_RESIZE == 0x2000000ULL);
CLASSERT(OBD_CONNECT_VBR == 0x80000000ULL);
CLASSERT(OBD_CONNECT_SKIP_ORPHAN == 0x400000000ULL);
+ CLASSERT(OBD_CONNECT_FULL20 == 0x800000000ULL);
/* Checks for struct obdo */
LASSERTF((int)sizeof(struct obdo) == 208, " found %lld\n",