diff --git a/lustre/include/lustre/lustre_idl.h b/lustre/include/lustre/lustre_idl.h index 21bc557862325b4c5f3311ad3d21ebec3e19ed88..02c19d84f2c9589e9c6ee2b7bdbe9e6df47602df 100644 --- a/lustre/include/lustre/lustre_idl.h +++ b/lustre/include/lustre/lustre_idl.h @@ -593,6 +593,9 @@ extern void lustre_swab_ptlrpc_body(struct ptlrpc_body *pb); #define DLM_LOCKREPLY_OFF 1 /* lockrep offset */ #define DLM_REPLY_REC_OFF 2 /* reply record offset */ +/* only use in req->rq_{req,rep}_swab_mask */ +#define MSG_PTLRPC_HEADER_OFF 31 + /* Flags that are operation-specific go in the top 16 bits. */ #define MSG_OP_FLAG_MASK 0xffff0000 #define MSG_OP_FLAG_SHIFT 16 diff --git a/lustre/include/lustre_net.h b/lustre/include/lustre_net.h index 7ff653c0cb238ab4ffc4902a8065b40b63ef95d0..a4377b5cbb8e99d64fdc04874928dc52d3cd27c4 100644 --- a/lustre/include/lustre_net.h +++ b/lustre/include/lustre_net.h @@ -502,6 +502,16 @@ static inline int lustre_rep_swabbed(struct ptlrpc_request *req, int index) return req->rq_rep_swab_mask & (1 << index); } +static inline int lustre_req_need_swab(struct ptlrpc_request *req) +{ + return req->rq_req_swab_mask & (1 << MSG_PTLRPC_HEADER_OFF); +} + +static inline int lustre_rep_need_swab(struct ptlrpc_request *req) +{ + return req->rq_rep_swab_mask & (1 << MSG_PTLRPC_HEADER_OFF); +} + static inline const char * ptlrpc_rqphase2str(const struct ptlrpc_request *req) { @@ -987,7 +997,8 @@ int ptlrpc_import_recovery_state_machine(struct obd_import *imp); /* ptlrpc/pack_generic.c */ int ptlrpc_reconnect_import(struct obd_import *imp); -int lustre_msg_swabbed(struct lustre_msg *msg); +int ptlrpc_req_need_swab(struct ptlrpc_request *req, int inout, int index); +void ptlrpc_req_set_swabbed(struct ptlrpc_request *req, int inout, int index); int lustre_msg_check_version(struct lustre_msg *msg, __u32 version); void lustre_init_msg_v2(struct lustre_msg_v2 *msg, int count, __u32 *lens, char **bufs); diff --git a/lustre/include/obd.h b/lustre/include/obd.h index b42e2c3736945f2b5be5a797e836c6dffd802c2e..4252e5fce46d38fec8c3f0ef7a543db917c4fb98 100644 --- a/lustre/include/obd.h +++ b/lustre/include/obd.h @@ -1595,7 +1595,7 @@ static inline const struct lsm_operations *lsm_op_find(int magic) case LOV_MAGIC_V3: return &lsm_v3_ops; default: - CERROR("Cannot recognize lsm_magic %d\n", magic); + CERROR("Cannot recognize lsm_magic %x\n", magic); return NULL; } } diff --git a/lustre/osc/osc_request.c b/lustre/osc/osc_request.c index a00185f085a45aa397760d60957879ae2fa08fa9..38c67182466f084656957fefac7eb3bbccd8d056 100644 --- a/lustre/osc/osc_request.c +++ b/lustre/osc/osc_request.c @@ -950,7 +950,7 @@ static int check_write_rcs(struct ptlrpc_request *req, CDEBUG(D_INFO, "Missing/short RC vector on BRW_WRITE reply\n"); return(-EPROTO); } - if (lustre_msg_swabbed(req->rq_repmsg)) + if (lustre_rep_need_swab(req)) for (i = 0; i < niocount; i++) __swab32s(&remote_rcs[i]); diff --git a/lustre/ost/ost_handler.c b/lustre/ost/ost_handler.c index 3e6f0f2cf31a74f0bfcc803feed1e6ae42a51d6a..1f613e1b4351af10ad99c19ad545027c917897eb 100644 --- a/lustre/ost/ost_handler.c +++ b/lustre/ost/ost_handler.c @@ -625,7 +625,8 @@ static int ost_brw_read(struct ptlrpc_request *req, struct obd_trans_info *oti) CERROR("Missing/short niobuf\n"); GOTO(out, rc = -EFAULT); } - if (lustre_msg_swabbed(req->rq_reqmsg)) { /* swab remaining niobufs */ + + if (lustre_req_need_swab(req)) { /* swab remaining niobufs */ for (i = 1; i < niocount; i++) lustre_swab_niobuf_remote (&remote_nb[i]); } @@ -864,7 +865,7 @@ static int ost_brw_write(struct ptlrpc_request *req, struct obd_trans_info *oti) if (exp->exp_failed) GOTO(out, rc = -ENOTCONN); - swab = lustre_msg_swabbed(req->rq_reqmsg); + swab = lustre_req_need_swab(req); body = lustre_swab_reqbuf(req, REQ_REC_OFF, sizeof(*body), lustre_swab_ost_body); if (body == NULL) { diff --git a/lustre/ptlrpc/client.c b/lustre/ptlrpc/client.c index de5f94bc74a50a112cfd226a85a5d1353ec2a875..9385600ac1fec1a875d3c883feb3b959c98494bd 100644 --- a/lustre/ptlrpc/client.c +++ b/lustre/ptlrpc/client.c @@ -284,16 +284,20 @@ static int unpack_reply(struct ptlrpc_request *req) req->rq_rep_swab_mask = 0; rc = lustre_unpack_msg(req->rq_repmsg, req->rq_replen); - if (rc) { + if (rc < 0) { DEBUG_REQ(D_ERROR, req, "unpack_rep failed: %d", rc); return(-EPROTO); } + if (rc > 0) + lustre_set_rep_swabbed(req, MSG_PTLRPC_HEADER_OFF); + rc = lustre_unpack_rep_ptlrpc_body(req, MSG_PTLRPC_BODY_OFF); if (rc) { DEBUG_REQ(D_ERROR, req, "unpack ptlrpc body failed: %d", rc); return(-EPROTO); } + return 0; } diff --git a/lustre/ptlrpc/layout.c b/lustre/ptlrpc/layout.c index 562335c269293b32be4d2137dcfce75c01fa14a8..531ef1200083038166cf5160d1271d3aeeab9a01 100644 --- a/lustre/ptlrpc/layout.c +++ b/lustre/ptlrpc/layout.c @@ -1351,7 +1351,7 @@ static int __req_capsule_offset(const struct req_capsule *pill, pill->rc_fmt->rf_name, field->rmf_name, offset, loc); offset --; - LASSERT(0 <= offset && offset < (sizeof(pill->rc_swabbed) << 3)); + LASSERT(0 <= offset && offset < REQ_MAX_FIELD_NR); return offset; } @@ -1365,6 +1365,7 @@ static void *__req_capsule_get(struct req_capsule *pill, void *value; int len; int offset; + int inout = loc == RCL_CLIENT; void *(*getter)(struct lustre_msg *m, int n, int minlen); @@ -1395,12 +1396,12 @@ static void *__req_capsule_get(struct req_capsule *pill, value = getter(msg, offset, len); swabber = swabber ?: field->rmf_swabber; - if (!(pill->rc_swabbed & (1 << offset)) && loc != pill->rc_loc && - swabber != NULL && value != NULL && - lustre_msg_swabbed(msg)) { + if (ptlrpc_req_need_swab(pill->rc_req, inout, offset) && + swabber != NULL && value != NULL) { swabber(value); - pill->rc_swabbed |= (1 << offset); + ptlrpc_req_set_swabbed(pill->rc_req, inout, offset); } + if (value == NULL) { DEBUG_REQ(D_ERROR, pill->rc_req, "Wrong buffer for field `%s' (%d of %d) " @@ -1544,7 +1545,6 @@ void req_capsule_extend(struct req_capsule *pill, const struct req_format *fmt) FMT_FIELD(old, i, j)->rmf_size); } /* last field should be returned to the unswabbed state */ - pill->rc_swabbed &= ~(__u32)(1 << j); pill->rc_fmt = fmt; } EXPORT_SYMBOL(req_capsule_extend); diff --git a/lustre/ptlrpc/pack_generic.c b/lustre/ptlrpc/pack_generic.c index 42790f125b17e64a1e6322ac0f422d400ead8db0..028a1ba97bbcd4634b8b659209f57984df90d076 100644 --- a/lustre/ptlrpc/pack_generic.c +++ b/lustre/ptlrpc/pack_generic.c @@ -72,11 +72,55 @@ int lustre_msg_hdr_size(__u32 magic, int count) } EXPORT_SYMBOL(lustre_msg_hdr_size); -int lustre_msg_swabbed(struct lustre_msg *msg) +int lustre_msg_need_swab(struct lustre_msg *msg) { return (msg->lm_magic == LUSTRE_MSG_MAGIC_V2_SWABBED); } +/** + * \ret 0 - if need swabbed + * \ret 1 - otherwise + */ +static int ptlrpc_reqbuf_need_swab(struct ptlrpc_request *req, int index) +{ + return (lustre_req_need_swab(req) && !lustre_req_swabbed(req, index)); +} + +/** + * \ret 0 - if need swabbed + * \ret 1 - otherwise + */ +static int ptlrpc_repbuf_need_swab(struct ptlrpc_request *req, int index) +{ + return (lustre_rep_need_swab(req) && !lustre_rep_swabbed(req, index)); +} + +/** + * ptlrpc_req_need_swab - check the @req if need swab. + * @req - ptlrpc_request need to look at. + * @inout - =1 reqbuf, =0 repbuf. + * @index - message offset + * + * \ret 0 - swabbed + * \ret 1 - need swab + */ +int ptlrpc_req_need_swab(struct ptlrpc_request *req, int inout, int index) +{ + if (inout) + return ptlrpc_reqbuf_need_swab(req, index); + else + return ptlrpc_repbuf_need_swab(req, index); +} + +void ptlrpc_req_set_swabbed(struct ptlrpc_request *req, int inout, int index) +{ + if(inout) + lustre_set_req_swabbed(req, index); + else + lustre_set_rep_swabbed(req, index); +} + + static inline int lustre_msg_check_version_v2(struct lustre_msg_v2 *msg, __u32 version) { @@ -88,11 +132,9 @@ int lustre_msg_check_version(struct lustre_msg *msg, __u32 version) { switch (msg->lm_magic) { case LUSTRE_MSG_MAGIC_V1: - case LUSTRE_MSG_MAGIC_V1_SWABBED: CERROR("msg v1 not supported - please upgrade you system\n"); return -EINVAL; case LUSTRE_MSG_MAGIC_V2: - case LUSTRE_MSG_MAGIC_V2_SWABBED: return lustre_msg_check_version_v2(msg, version); default: CERROR("incorrect message magic: %08x\n", msg->lm_magic); @@ -497,9 +539,9 @@ static int lustre_unpack_msg_v2(struct lustre_msg_v2 *m, int len) return -EINVAL; } - flipped = lustre_msg_swabbed(m); - + flipped = lustre_msg_need_swab(m); if (flipped) { + __swab32s(&m->lm_magic); __swab32s(&m->lm_bufcount); __swab32s(&m->lm_secflvr); __swab32s(&m->lm_repsize); @@ -516,7 +558,7 @@ static int lustre_unpack_msg_v2(struct lustre_msg_v2 *m, int len) len, m->lm_bufcount); return -EINVAL; } - + for (i = 0; i < m->lm_bufcount; i++) { if (flipped) __swab32s(&m->lm_buflens[i]); @@ -531,7 +573,7 @@ static int lustre_unpack_msg_v2(struct lustre_msg_v2 *m, int len) return -EINVAL; } - return 0; + return flipped; } int lustre_unpack_msg(struct lustre_msg *m, int len) @@ -567,18 +609,22 @@ int lustre_unpack_msg(struct lustre_msg *m, int len) RETURN(rc); } -static inline int lustre_unpack_ptlrpc_body_v2(struct lustre_msg_v2 *m, +static inline int lustre_unpack_ptlrpc_body_v2(struct ptlrpc_request *req, + int inout, int offset) { 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)); if (!pb) { CERROR("error unpacking ptlrpc body\n"); return -EFAULT; } - if (lustre_msg_swabbed(m)) + if (ptlrpc_req_need_swab(req, inout, offset)) { lustre_swab_ptlrpc_body(pb); + ptlrpc_req_set_swabbed(req, inout, offset); + } if ((pb->pb_version & ~LUSTRE_VERSION_MASK) != PTLRPC_MSG_VERSION) { CERROR("wrong lustre_msg version %08x\n", pb->pb_version); @@ -592,9 +638,7 @@ int lustre_unpack_req_ptlrpc_body(struct ptlrpc_request *req, int offset) { switch (req->rq_reqmsg->lm_magic) { case LUSTRE_MSG_MAGIC_V2: - case LUSTRE_MSG_MAGIC_V2_SWABBED: - lustre_set_req_swabbed(req, offset); - return lustre_unpack_ptlrpc_body_v2(req->rq_reqmsg, offset); + return lustre_unpack_ptlrpc_body_v2(req, 1, offset); default: CERROR("bad lustre msg magic: %#08X\n", req->rq_reqmsg->lm_magic); @@ -606,9 +650,7 @@ int lustre_unpack_rep_ptlrpc_body(struct ptlrpc_request *req, int offset) { switch (req->rq_repmsg->lm_magic) { case LUSTRE_MSG_MAGIC_V2: - case LUSTRE_MSG_MAGIC_V2_SWABBED: - lustre_set_rep_swabbed(req, offset); - return lustre_unpack_ptlrpc_body_v2(req->rq_repmsg, offset); + return lustre_unpack_ptlrpc_body_v2(req, 0, offset); default: CERROR("bad lustre msg magic: %#08X\n", req->rq_repmsg->lm_magic); @@ -744,7 +786,7 @@ void *lustre_swab_buf(struct lustre_msg *msg, int index, int min_size, if (ptr == NULL) return NULL; - if (swabber != NULL && lustre_msg_swabbed(msg)) + if (swabber != NULL) ((void (*)(void *))swabber)(ptr); return ptr; @@ -753,6 +795,9 @@ void *lustre_swab_buf(struct lustre_msg *msg, int index, int min_size, void *lustre_swab_reqbuf(struct ptlrpc_request *req, int index, int min_size, void *swabber) { + if (!ptlrpc_reqbuf_need_swab(req, index)) + swabber = NULL; + lustre_set_req_swabbed(req, index); return lustre_swab_buf(req->rq_reqmsg, index, min_size, swabber); } @@ -760,6 +805,9 @@ void *lustre_swab_reqbuf(struct ptlrpc_request *req, int index, int min_size, void *lustre_swab_repbuf(struct ptlrpc_request *req, int index, int min_size, void *swabber) { + if (!ptlrpc_repbuf_need_swab(req, index)) + swabber = NULL; + lustre_set_rep_swabbed(req, index); return lustre_swab_buf(req->rq_repmsg, index, min_size, swabber); } diff --git a/lustre/ptlrpc/ptlrpc_internal.h b/lustre/ptlrpc/ptlrpc_internal.h index bdea8bd6724fd7d5d49e253743a86301cdfb204a..a357b38daf5a0984f93c3828baf53902a6f66172 100644 --- a/lustre/ptlrpc/ptlrpc_internal.h +++ b/lustre/ptlrpc/ptlrpc_internal.h @@ -90,6 +90,7 @@ void ptlrpc_add_bulk_page(struct ptlrpc_bulk_desc *desc, cfs_page_t *page, void ptl_rpc_wipe_bulk_pages(struct ptlrpc_bulk_desc *desc); /* pack_generic.c */ +int lustre_msg_need_swab(struct lustre_msg *msg); struct ptlrpc_reply_state *lustre_get_emerg_rs(struct ptlrpc_service *svc); void lustre_put_emerg_rs(struct ptlrpc_reply_state *rs); diff --git a/lustre/ptlrpc/ptlrpc_module.c b/lustre/ptlrpc/ptlrpc_module.c index 76e07271315d891c1f71012130e3b4f9e76b8547..16c47c44697c520c36f1fdf4ea6fe404cff9d15e 100644 --- a/lustre/ptlrpc/ptlrpc_module.c +++ b/lustre/ptlrpc/ptlrpc_module.c @@ -213,7 +213,6 @@ EXPORT_SYMBOL(ptlrpc_daemonize); EXPORT_SYMBOL(ptlrpc_service_health_check); /* pack_generic.c */ -EXPORT_SYMBOL(lustre_msg_swabbed); EXPORT_SYMBOL(lustre_msg_check_version); EXPORT_SYMBOL(lustre_pack_request); EXPORT_SYMBOL(lustre_pack_reply); diff --git a/lustre/ptlrpc/sec.c b/lustre/ptlrpc/sec.c index 977ac89d2d181b983d692e3d060d0b36a40f09ac..6e6b5d1e64711d0f370a54f9e75a0e20da6b7759 100644 --- a/lustre/ptlrpc/sec.c +++ b/lustre/ptlrpc/sec.c @@ -2223,7 +2223,7 @@ int sptlrpc_unpack_user_desc(struct lustre_msg *msg, int offset) if (!pud) return -EINVAL; - if (lustre_msg_swabbed(msg)) { + if (lustre_msg_need_swab(msg)) { __swab32s(&pud->pud_uid); __swab32s(&pud->pud_gid); __swab32s(&pud->pud_fsuid); @@ -2244,7 +2244,7 @@ int sptlrpc_unpack_user_desc(struct lustre_msg *msg, int offset) return -EINVAL; } - if (lustre_msg_swabbed(msg)) { + if (lustre_msg_need_swab(msg)) { for (i = 0; i < pud->pud_ngroups; i++) __swab32s(&pud->pud_groups[i]); } diff --git a/lustre/ptlrpc/service.c b/lustre/ptlrpc/service.c index 05ff23d5fc95f2346764af2c55d90f50e5d6ff07..6507f1a66dc7eda7d37a7efd1e9edd1693b06340 100644 --- a/lustre/ptlrpc/service.c +++ b/lustre/ptlrpc/service.c @@ -960,13 +960,16 @@ ptlrpc_server_handle_req_in(struct ptlrpc_service *svc) req->rq_req_swab_mask = 0; rc = lustre_unpack_msg(req->rq_reqmsg, req->rq_reqlen); - if (rc != 0) { + if (rc < 0) { CERROR("error unpacking request: ptl %d from %s x"LPU64"\n", svc->srv_req_portal, libcfs_id2str(req->rq_peer), req->rq_xid); goto err_req; } + if (rc > 0) + lustre_set_req_swabbed(req, MSG_PTLRPC_HEADER_OFF); + rc = lustre_unpack_req_ptlrpc_body(req, MSG_PTLRPC_BODY_OFF); if (rc) { CERROR ("error unpacking ptlrpc body: ptl %d from %s x"