From 3ca197b4aa3b2fc11da9a946db597e73a62fe149 Mon Sep 17 00:00:00 2001 From: Li Wei Date: Tue, 23 Jul 2013 23:19:49 +0800 Subject: [PATCH] LU-3539 osp: Fix a series of UPDATE_OBJ endianness bugs Current UPDATE_OBJ code have the following problems: - Fields in "struct update_buf", except for ub_bufs, are sent in senders' host endianness but expected to be little-endian by receivers. - Fields in "struct update", except for u_bufs, are sent in little endianness but used without swabbing by receivers. - Most u_bufs are sent in little endianness, but some are in senders' host endianness. - Sizes for a couple of string buffers in osp_md_declare_xattr_set() and osp_md_xattr_get() are off-by-one. - Error numbers in UPDATE_OBJ replies are not translated on both sides. This patch fixes them by sending all data in UPDATE_OBJ requests and replies in host endianness, following Lustre's usual practices. Change-Id: Id3ffb248af181b4beff2b62c9cb46fc6d9f9e673 Signed-off-by: Li Wei Reviewed-on: http://review.whamcloud.com/7088 Tested-by: Jenkins Reviewed-by: Alex Zhuravlev Tested-by: Maloo Reviewed-by: Andreas Dilger Reviewed-by: Oleg Drokin --- lustre/include/obd_class.h | 3 --- lustre/obdclass/obdo.c | 35 ----------------------------------- lustre/osp/osp_internal.h | 1 + lustre/osp/osp_md_object.c | 11 ++++------- lustre/osp/osp_object.c | 13 ++++++++++--- lustre/osp/osp_trans.c | 4 ++-- lustre/target/out_handler.c | 8 +++++--- 7 files changed, 22 insertions(+), 53 deletions(-) diff --git a/lustre/include/obd_class.h b/lustre/include/obd_class.h index ae759e7..2f71625 100644 --- a/lustre/include/obd_class.h +++ b/lustre/include/obd_class.h @@ -340,9 +340,6 @@ void md_from_obdo(struct md_op_data *op_data, struct obdo *oa, obd_flag valid); void obdo_from_md(struct obdo *oa, struct md_op_data *op_data, unsigned int valid); -void obdo_cpu_to_le(struct obdo *dobdo, struct obdo *sobdo); -void obdo_le_to_cpu(struct obdo *dobdo, struct obdo *sobdo); - #define OBT(dev) (dev)->obd_type #define OBP(dev, op) (dev)->obd_type->typ_dt_ops->o_ ## op #define MDP(dev, op) (dev)->obd_type->typ_md_ops->m_ ## op diff --git a/lustre/obdclass/obdo.c b/lustre/obdclass/obdo.c index b7587d4..e99b17a 100644 --- a/lustre/obdclass/obdo.c +++ b/lustre/obdclass/obdo.c @@ -332,38 +332,3 @@ void obdo_from_md(struct obdo *oa, struct md_op_data *op_data, } } EXPORT_SYMBOL(obdo_from_md); - -void obdo_cpu_to_le(struct obdo *dobdo, struct obdo *sobdo) -{ - dobdo->o_size = cpu_to_le64(sobdo->o_size); - dobdo->o_mtime = cpu_to_le64(sobdo->o_mtime); - dobdo->o_atime = cpu_to_le64(sobdo->o_atime); - dobdo->o_ctime = cpu_to_le64(sobdo->o_ctime); - dobdo->o_blocks = cpu_to_le64(sobdo->o_blocks); - dobdo->o_mode = cpu_to_le32(sobdo->o_mode); - dobdo->o_uid = cpu_to_le32(sobdo->o_uid); - dobdo->o_gid = cpu_to_le32(sobdo->o_gid); - dobdo->o_flags = cpu_to_le32(sobdo->o_flags); - dobdo->o_nlink = cpu_to_le32(sobdo->o_nlink); - dobdo->o_blksize = cpu_to_le32(sobdo->o_blksize); - dobdo->o_valid = cpu_to_le64(sobdo->o_valid); -} -EXPORT_SYMBOL(obdo_cpu_to_le); - -void obdo_le_to_cpu(struct obdo *dobdo, struct obdo *sobdo) -{ - dobdo->o_size = le64_to_cpu(sobdo->o_size); - dobdo->o_mtime = le64_to_cpu(sobdo->o_mtime); - dobdo->o_atime = le64_to_cpu(sobdo->o_atime); - dobdo->o_ctime = le64_to_cpu(sobdo->o_ctime); - dobdo->o_blocks = le64_to_cpu(sobdo->o_blocks); - dobdo->o_mode = le32_to_cpu(sobdo->o_mode); - dobdo->o_uid = le32_to_cpu(sobdo->o_uid); - dobdo->o_gid = le32_to_cpu(sobdo->o_gid); - dobdo->o_flags = le32_to_cpu(sobdo->o_flags); - dobdo->o_nlink = le32_to_cpu(sobdo->o_nlink); - dobdo->o_blksize = le32_to_cpu(sobdo->o_blksize); - dobdo->o_valid = le64_to_cpu(sobdo->o_valid); -} -EXPORT_SYMBOL(obdo_le_to_cpu); - diff --git a/lustre/osp/osp_internal.h b/lustre/osp/osp_internal.h index d405176..aa28014 100644 --- a/lustre/osp/osp_internal.h +++ b/lustre/osp/osp_internal.h @@ -454,6 +454,7 @@ static inline int osp_is_fid_client(struct osp_device *osp) typedef int (*osp_async_update_interpterer_t)(const struct lu_env *env, struct object_update_reply *reply, + struct ptlrpc_request *req, struct osp_object *obj, void *data, int index, int rc); diff --git a/lustre/osp/osp_md_object.c b/lustre/osp/osp_md_object.c index 9bed8da..e331bfa 100644 --- a/lustre/osp/osp_md_object.c +++ b/lustre/osp/osp_md_object.c @@ -64,19 +64,16 @@ int osp_md_declare_object_create(const struct lu_env *env, osi->osi_obdo.o_valid = 0; obdo_from_la(&osi->osi_obdo, attr, attr->la_valid); lustre_set_wire_obdo(NULL, &osi->osi_obdo, &osi->osi_obdo); - obdo_cpu_to_le(&osi->osi_obdo, &osi->osi_obdo); bufs[0] = (char *)&osi->osi_obdo; buf_count = 1; fid1 = (struct lu_fid *)lu_object_fid(&dt->do_lu); if (hint != NULL && hint->dah_parent) { struct lu_fid *fid2; - struct lu_fid *tmp_fid = &osi->osi_fid; fid2 = (struct lu_fid *)lu_object_fid(&hint->dah_parent->do_lu); - fid_cpu_to_le(tmp_fid, fid2); - sizes[1] = sizeof(*tmp_fid); - bufs[1] = (char *)tmp_fid; + sizes[1] = sizeof(*fid2); + bufs[1] = (char *)fid2; buf_count++; } @@ -248,7 +245,6 @@ int osp_md_declare_attr_set(const struct lu_env *env, struct dt_object *dt, obdo_from_la(&osi->osi_obdo, (struct lu_attr *)attr, attr->la_valid); lustre_set_wire_obdo(NULL, &osi->osi_obdo, &osi->osi_obdo); - obdo_cpu_to_le(&osi->osi_obdo, &osi->osi_obdo); buf = (char *)&osi->osi_obdo; fid = (struct lu_fid *)lu_object_fid(&dt->do_lu); @@ -376,7 +372,8 @@ static int osp_md_index_lookup(const struct lu_env *env, struct dt_object *dt, } fid = lbuf->lb_buf; - fid_le_to_cpu(fid, fid); + if (ptlrpc_rep_need_swab(req)) + lustre_swab_lu_fid(fid); if (!fid_is_sane(fid)) { CERROR("%s: lookup "DFID" %s invalid fid "DFID"\n", dt_dev->dd_lu_dev.ld_obd->obd_name, diff --git a/lustre/osp/osp_object.c b/lustre/osp/osp_object.c index 78e2250..dcdadf3 100644 --- a/lustre/osp/osp_object.c +++ b/lustre/osp/osp_object.c @@ -208,6 +208,7 @@ static inline void osp_oac_xattr_put(struct osp_xattr_entry *oxe) static int osp_get_attr_from_reply(const struct lu_env *env, struct object_update_reply *reply, + struct ptlrpc_request *req, struct lu_attr *attr, struct osp_object *obj, int index) { @@ -225,7 +226,10 @@ static int osp_get_attr_from_reply(const struct lu_env *env, if (rbuf->lb_len != sizeof(*wobdo)) return -EPROTO; - obdo_le_to_cpu(wobdo, wobdo); + LASSERT(req != NULL); + if (ptlrpc_req_need_swab(req)) + lustre_swab_obdo(wobdo); + lustre_get_wire_obdo(NULL, lobdo, wobdo); spin_lock(&obj->opo_lock); if (obj->opo_ooa != NULL) { @@ -244,6 +248,7 @@ static int osp_get_attr_from_reply(const struct lu_env *env, static int osp_attr_get_interpterer(const struct lu_env *env, struct object_update_reply *reply, + struct ptlrpc_request *req, struct osp_object *obj, void *data, int index, int rc) { @@ -255,7 +260,8 @@ static int osp_attr_get_interpterer(const struct lu_env *env, osp2lu_obj(obj)->lo_header->loh_attr |= LOHA_EXISTS; obj->opo_non_exist = 0; - return osp_get_attr_from_reply(env, reply, NULL, obj, index); + return osp_get_attr_from_reply(env, reply, req, NULL, obj, + index); } else { if (rc == -ENOENT) { osp2lu_obj(obj)->lo_header->loh_attr &= ~LOHA_EXISTS; @@ -360,7 +366,7 @@ int osp_attr_get(const struct lu_env *env, struct dt_object *dt, if (reply == NULL || reply->ourp_magic != UPDATE_REPLY_MAGIC) GOTO(out, rc = -EPROTO); - rc = osp_get_attr_from_reply(env, reply, attr, obj, 0); + rc = osp_get_attr_from_reply(env, reply, req, attr, obj, 0); if (rc != 0) GOTO(out, rc); @@ -500,6 +506,7 @@ static int osp_attr_set(const struct lu_env *env, struct dt_object *dt, static int osp_xattr_get_interpterer(const struct lu_env *env, struct object_update_reply *reply, + struct ptlrpc_request *req, struct osp_object *obj, void *data, int index, int rc) { diff --git a/lustre/osp/osp_trans.c b/lustre/osp/osp_trans.c index 5aa0fb6..fd137d1 100644 --- a/lustre/osp/osp_trans.c +++ b/lustre/osp/osp_trans.c @@ -119,7 +119,7 @@ static int osp_async_update_interpret(const struct lu_env *env, rc1 = -EINVAL; } - oaui->oaui_interpterer(env, reply, oaui->oaui_obj, + oaui->oaui_interpterer(env, reply, req, oaui->oaui_obj, oaui->oaui_data, index, rc1); osp_async_update_item_fini(env, oaui); index++; @@ -147,7 +147,7 @@ int osp_unplug_async_update(const struct lu_env *env, list_for_each_entry_safe(oaui, next, &update->dur_cb_items, oaui_list) { list_del_init(&oaui->oaui_list); - oaui->oaui_interpterer(env, NULL, oaui->oaui_obj, + oaui->oaui_interpterer(env, NULL, NULL, oaui->oaui_obj, oaui->oaui_data, 0, rc); osp_async_update_item_fini(env, oaui); } diff --git a/lustre/target/out_handler.c b/lustre/target/out_handler.c index efc8b41..55e826d 100644 --- a/lustre/target/out_handler.c +++ b/lustre/target/out_handler.c @@ -211,7 +211,8 @@ static int out_create(struct tgt_session_info *tsi) RETURN(err_serious(-EPROTO)); } - obdo_le_to_cpu(wobdo, wobdo); + if (ptlrpc_req_need_swab(tsi->tsi_pill->rc_req)) + lustre_swab_obdo(wobdo); lustre_get_wire_obdo(NULL, lobdo, wobdo); la_from_obdo(attr, lobdo, lobdo->o_valid); @@ -323,7 +324,9 @@ static int out_attr_set(struct tgt_session_info *tsi) attr->la_valid = 0; attr->la_valid = 0; - obdo_le_to_cpu(wobdo, wobdo); + + if (ptlrpc_req_need_swab(tsi->tsi_pill->rc_req)) + lustre_swab_obdo(wobdo); lustre_get_wire_obdo(NULL, lobdo, wobdo); la_from_obdo(attr, lobdo, lobdo->o_valid); @@ -399,7 +402,6 @@ static int out_attr_get(struct tgt_session_info *tsi) obdo->o_valid = 0; obdo_from_la(obdo, la, la->la_valid); - obdo_cpu_to_le(obdo, obdo); lustre_set_wire_obdo(NULL, obdo, obdo); out_unlock: -- 1.8.3.1