From 5e833ccec1d779275656cfcae821e06c90a8604b Mon Sep 17 00:00:00 2001 From: Nicolas Williams Date: Mon, 25 Jan 2010 16:09:10 -0600 Subject: [PATCH] b=21490 1.8<->2.0 interop: in 2.0 server and 1.8 client env. read 1. 8 file hung The fix for bug 18631 introduced an interop bug for 1.8.x clients with 2.0 OSTs. The problem was that a zero-length RMF_RCS was included in the OST_BRW replies for READs, which caused the RPC header to have eight more bytes for storing the length of that zero-length buffer. The fix is to split RQF_OST_BRW into two, one for READs and one for WRITEs, with RMF_RCS present only in the reply for OST_BRW_WRITE. i=robert.read@sun.com i=tom.wang@sun.com --- lustre/include/lustre_req_layout.h | 3 ++- lustre/osc/osc_request.c | 6 ++---- lustre/ost/ost_handler.c | 12 ++++++++---- lustre/ptlrpc/layout.c | 20 +++++++++++++++----- 4 files changed, 27 insertions(+), 14 deletions(-) diff --git a/lustre/include/lustre_req_layout.h b/lustre/include/lustre_req_layout.h index 0cd88b4..ef8d2ec 100644 --- a/lustre/include/lustre_req_layout.h +++ b/lustre/include/lustre_req_layout.h @@ -186,7 +186,8 @@ extern const struct req_format RQF_OST_CREATE; extern const struct req_format RQF_OST_PUNCH; extern const struct req_format RQF_OST_SYNC; extern const struct req_format RQF_OST_DESTROY; -extern const struct req_format RQF_OST_BRW; +extern const struct req_format RQF_OST_BRW_READ; +extern const struct req_format RQF_OST_BRW_WRITE; extern const struct req_format RQF_OST_STATFS; extern const struct req_format RQF_OST_SET_GRANT_INFO; extern const struct req_format RQF_OST_GET_INFO_GENERIC; diff --git a/lustre/osc/osc_request.c b/lustre/osc/osc_request.c index 32394f7..94998c0 100644 --- a/lustre/osc/osc_request.c +++ b/lustre/osc/osc_request.c @@ -1254,10 +1254,10 @@ static int osc_brw_prep_request(int cmd, struct client_obd *cli,struct obdo *oa, opc = OST_WRITE; req = ptlrpc_request_alloc_pool(cli->cl_import, cli->cl_import->imp_rq_pool, - &RQF_OST_BRW); + &RQF_OST_BRW_WRITE); } else { opc = OST_READ; - req = ptlrpc_request_alloc(cli->cl_import, &RQF_OST_BRW); + req = ptlrpc_request_alloc(cli->cl_import, &RQF_OST_BRW_READ); } if (req == NULL) RETURN(-ENOMEM); @@ -1391,8 +1391,6 @@ static int osc_brw_prep_request(int cmd, struct client_obd *cli,struct obdo *oa, body->oa.o_flags |= cksum_type_pack(cli->cl_cksum_type); body->oa.o_valid |= OBD_MD_FLCKSUM | OBD_MD_FLFLAGS; } - req_capsule_set_size(pill, &RMF_RCS, RCL_SERVER, 0); - /* 1 RC for the whole I/O */ } ptlrpc_request_set_replen(req); diff --git a/lustre/ost/ost_handler.c b/lustre/ost/ost_handler.c index c8473da..9c20008 100644 --- a/lustre/ost/ost_handler.c +++ b/lustre/ost/ost_handler.c @@ -681,7 +681,6 @@ static int ost_brw_read(struct ptlrpc_request *req, struct obd_trans_info *oti) } } - req_capsule_set_size(&req->rq_pill, &RMF_RCS, RCL_SERVER, 0); rc = req_capsule_server_pack(&req->rq_pill); if (rc) GOTO(out, rc); @@ -1898,7 +1897,12 @@ static int ost_hpreq_handler(struct ptlrpc_request *req) * it doesn't change). */ req_capsule_init(&req->rq_pill, req, RCL_SERVER); - req_capsule_set(&req->rq_pill, &RQF_OST_BRW); + if (opc == OST_READ) + req_capsule_set(&req->rq_pill, + &RQF_OST_BRW_READ); + else + req_capsule_set(&req->rq_pill, + &RQF_OST_BRW_WRITE); body = req_capsule_client_get(&req->rq_pill, &RMF_OST_BODY); @@ -2081,7 +2085,7 @@ int ost_handle(struct ptlrpc_request *req) rc = ost_setattr(req->rq_export, req, oti); break; case OST_WRITE: - req_capsule_set(&req->rq_pill, &RQF_OST_BRW); + req_capsule_set(&req->rq_pill, &RQF_OST_BRW_WRITE); CDEBUG(D_INODE, "write\n"); /* req->rq_request_portal would be nice, if it was set */ if (req->rq_rqbd->rqbd_service->srv_req_portal !=OST_IO_PORTAL){ @@ -2102,7 +2106,7 @@ int ost_handle(struct ptlrpc_request *req) /* ost_brw_write sends its own replies */ RETURN(rc); case OST_READ: - req_capsule_set(&req->rq_pill, &RQF_OST_BRW); + req_capsule_set(&req->rq_pill, &RQF_OST_BRW_READ); CDEBUG(D_INODE, "read\n"); /* req->rq_request_portal would be nice, if it was set */ if (req->rq_rqbd->rqbd_service->srv_req_portal !=OST_IO_PORTAL){ diff --git a/lustre/ptlrpc/layout.c b/lustre/ptlrpc/layout.c index 6ca074b..bf6b381 100644 --- a/lustre/ptlrpc/layout.c +++ b/lustre/ptlrpc/layout.c @@ -509,7 +509,12 @@ static const struct req_msg_field *ost_brw_client[] = { &RMF_CAPA1 }; -static const struct req_msg_field *ost_brw_server[] = { +static const struct req_msg_field *ost_brw_read_server[] = { + &RMF_PTLRPC_BODY, + &RMF_OST_BODY +}; + +static const struct req_msg_field *ost_brw_write_server[] = { &RMF_PTLRPC_BODY, &RMF_OST_BODY, &RMF_RCS @@ -591,7 +596,8 @@ static const struct req_format *req_formats[] = { &RQF_OST_PUNCH, &RQF_OST_SYNC, &RQF_OST_DESTROY, - &RQF_OST_BRW, + &RQF_OST_BRW_READ, + &RQF_OST_BRW_WRITE, &RQF_OST_STATFS, &RQF_OST_SET_GRANT_INFO, &RQF_OST_GET_INFO_GENERIC, @@ -1259,9 +1265,13 @@ const struct req_format RQF_OST_DESTROY = DEFINE_REQ_FMT0("OST_DESTROY", ost_destroy_client, ost_body_only); EXPORT_SYMBOL(RQF_OST_DESTROY); -const struct req_format RQF_OST_BRW = - DEFINE_REQ_FMT0("OST_BRW", ost_brw_client, ost_brw_server); -EXPORT_SYMBOL(RQF_OST_BRW); +const struct req_format RQF_OST_BRW_READ = + DEFINE_REQ_FMT0("OST_BRW_READ", ost_brw_client, ost_brw_read_server); +EXPORT_SYMBOL(RQF_OST_BRW_READ); + +const struct req_format RQF_OST_BRW_WRITE = + DEFINE_REQ_FMT0("OST_BRW_WRITE", ost_brw_client, ost_brw_write_server); +EXPORT_SYMBOL(RQF_OST_BRW_WRITE); const struct req_format RQF_OST_STATFS = DEFINE_REQ_FMT0("OST_STATFS", empty, obd_statfs_server); -- 1.8.3.1