X-Git-Url: https://git.whamcloud.com/?a=blobdiff_plain;f=lustre%2Fptlrpc%2Flayout.c;h=3fb3099f660886fa48487c70f92f7f45dc011058;hb=917655fc2938b90a9c246dd2d58408c42aa1658d;hp=3324543db902ccd6058de2dc2442a629b7804121;hpb=1fd63fcb045c91aa259068d3077b481652da0270;p=fs%2Flustre-release.git diff --git a/lustre/ptlrpc/layout.c b/lustre/ptlrpc/layout.c index 3324543..3fb3099 100644 --- a/lustre/ptlrpc/layout.c +++ b/lustre/ptlrpc/layout.c @@ -1198,8 +1198,8 @@ struct req_msg_field RMF_OST_ID = EXPORT_SYMBOL(RMF_OST_ID); struct req_msg_field RMF_FIEMAP_KEY = - DEFINE_MSGF("fiemap", 0, sizeof(struct ll_fiemap_info_key), - lustre_swab_fiemap, NULL); + DEFINE_MSGF("fiemap_key", 0, sizeof(struct ll_fiemap_info_key), + lustre_swab_fiemap_info_key, NULL); EXPORT_SYMBOL(RMF_FIEMAP_KEY); struct req_msg_field RMF_FIEMAP_VAL = @@ -1934,23 +1934,23 @@ EXPORT_SYMBOL(req_capsule_filled_sizes); */ int req_capsule_server_pack(struct req_capsule *pill) { - const struct req_format *fmt; - int count; - int rc; - - LASSERT(pill->rc_loc == RCL_SERVER); - fmt = pill->rc_fmt; - LASSERT(fmt != NULL); + const struct req_format *fmt; + int count; + int rc; - count = req_capsule_filled_sizes(pill, RCL_SERVER); - rc = lustre_pack_reply(pill->rc_req, count, - pill->rc_area[RCL_SERVER], NULL); - if (rc != 0) { - DEBUG_REQ(D_ERROR, pill->rc_req, - "Cannot pack %d fields in format `%s': ", - count, fmt->rf_name); - } - return rc; + LASSERT(pill->rc_loc == RCL_SERVER); + fmt = pill->rc_fmt; + LASSERT(fmt != NULL); + + count = req_capsule_filled_sizes(pill, RCL_SERVER); + rc = lustre_pack_reply(pill->rc_req, count, + pill->rc_area[RCL_SERVER], NULL); + if (rc != 0) { + DEBUG_REQ(D_ERROR, pill->rc_req, + "Cannot pack %d fields in format '%s'", + count, fmt->rf_name); + } + return rc; } EXPORT_SYMBOL(req_capsule_server_pack); @@ -2115,8 +2115,7 @@ static void *__req_capsule_get(struct req_capsule *pill, if (value == NULL) { DEBUG_REQ(D_ERROR, pill->rc_req, - "Wrong buffer for field `%s' (%u of %u) " - "in format `%s': %u vs. %u (%s)\n", + "Wrong buffer for field '%s' (%u of %u) in format '%s', %u vs. %u (%s)", field->rmf_name, offset, lustre_msg_bufcount(msg), fmt->rf_name, lustre_msg_buflen(msg, offset), len, rcl_names[loc]); @@ -2133,30 +2132,30 @@ static void *__req_capsule_get(struct req_capsule *pill, */ void __req_capsule_dump(struct req_capsule *pill, enum req_location loc) { - const struct req_format *fmt; - const struct req_msg_field *field; - __u32 len; - size_t i; - - fmt = pill->rc_fmt; + const struct req_format *fmt; + const struct req_msg_field *field; + __u32 len; + size_t i; - DEBUG_REQ(D_RPCTRACE, pill->rc_req, "BEGIN REQ CAPSULE DUMP\n"); - for (i = 0; i < fmt->rf_fields[loc].nr; ++i) { - field = FMT_FIELD(fmt, loc, i); - if (field->rmf_dumper == NULL) { - /* - * FIXME Add a default hex dumper for fields that don't - * have a specific dumper - */ - len = req_capsule_get_size(pill, field, loc); + fmt = pill->rc_fmt; + + DEBUG_REQ(D_RPCTRACE, pill->rc_req, "BEGIN REQ CAPSULE DUMP"); + for (i = 0; i < fmt->rf_fields[loc].nr; ++i) { + field = FMT_FIELD(fmt, loc, i); + if (field->rmf_dumper == NULL) { + /* + * FIXME Add a default hex dumper for fields that don't + * have a specific dumper + */ + len = req_capsule_get_size(pill, field, loc); CDEBUG(D_RPCTRACE, "Field %s has no dumper function;" "field size is %u\n", field->rmf_name, len); - } else { - /* It's the dumping side-effect that we're interested in */ - (void) __req_capsule_get(pill, field, loc, NULL, 1); - } - } - CDEBUG(D_RPCTRACE, "END REQ CAPSULE DUMP\n"); + } else { + /* It's dumping side-effect that we're interested in */ + (void) __req_capsule_get(pill, field, loc, NULL, 1); + } + } + CDEBUG(D_RPCTRACE, "END REQ CAPSULE DUMP\n"); } /** @@ -2499,17 +2498,22 @@ void req_capsule_shrink(struct req_capsule *pill, offset = __req_capsule_offset(pill, field, loc); - msg = __req_msg(pill, loc); - len = lustre_msg_buflen(msg, offset); + msg = __req_msg(pill, loc); + len = lustre_msg_buflen(msg, offset); LASSERTF(newlen <= len, "%s:%s, oldlen=%u, newlen=%u\n", - fmt->rf_name, field->rmf_name, len, newlen); - - if (loc == RCL_CLIENT) - pill->rc_req->rq_reqlen = lustre_shrink_msg(msg, offset, newlen, - 1); - else - pill->rc_req->rq_replen = lustre_shrink_msg(msg, offset, newlen, - 1); + fmt->rf_name, field->rmf_name, len, newlen); + + if (loc == RCL_CLIENT) { + pill->rc_req->rq_reqlen = lustre_shrink_msg(msg, offset, newlen, + 1); + } else { + pill->rc_req->rq_replen = lustre_shrink_msg(msg, offset, newlen, + 1); + /* update also field size in reply lenghts arrays for possible + * reply re-pack due to req_capsule_server_grow() call. + */ + req_capsule_set_size(pill, field, loc, newlen); + } } EXPORT_SYMBOL(req_capsule_shrink); @@ -2517,46 +2521,57 @@ int req_capsule_server_grow(struct req_capsule *pill, const struct req_msg_field *field, __u32 newlen) { - struct ptlrpc_reply_state *rs = pill->rc_req->rq_reply_state, *nrs; - char *from, *to; + struct ptlrpc_reply_state *rs = pill->rc_req->rq_reply_state, *nrs; + char *from, *to; int rc; __u32 offset, len; - 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 ((__u32)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 */ + 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); + + CDEBUG(D_INFO, "Reply packed: %d, allocated: %d, field len %d -> %d\n", + lustre_packed_msg_size(rs->rs_msg), rs->rs_repbuf_len, + len, newlen); + + req_capsule_set_size(pill, field, RCL_SERVER, newlen); + /** + * There can be enough space in current reply buffer, make sure + * that rs_repbuf is not a wrapper but real reply msg, otherwise + * re-packing is still needed. + */ + if (rs->rs_msg == rs->rs_repbuf && + rs->rs_repbuf_len >= + lustre_packed_msg_size(rs->rs_msg) - len + newlen) { + pill->rc_req->rq_replen = lustre_grow_msg(rs->rs_msg, offset, + newlen); + return 0; + } + + /* Re-allocate replay state */ + pill->rc_req->rq_reply_state = NULL; + rc = req_capsule_server_pack(pill); + if (rc) { + /* put old values back, the caller should decide what to do */ + req_capsule_set_size(pill, field, RCL_SERVER, len); + pill->rc_req->rq_reply_state = rs; + return rc; + } + nrs = pill->rc_req->rq_reply_state; + LASSERT(lustre_packed_msg_size(nrs->rs_msg) > + lustre_packed_msg_size(rs->rs_msg)); + + /* Now we need only buffers, copy them and grow the needed one */ + to = lustre_msg_buf(nrs->rs_msg, 0, 0); + from = lustre_msg_buf(rs->rs_msg, 0, 0); + len = (char *)rs->rs_msg + lustre_packed_msg_size(rs->rs_msg) - from; + memcpy(to, from, len); + pill->rc_req->rq_replen = lustre_grow_msg(nrs->rs_msg, offset, newlen); + if (rs->rs_difficult) { /* copy rs data */ int i;