From e4d2d4ff74a103e4288d7581b40020eaff22b139 Mon Sep 17 00:00:00 2001 From: James Simmons Date: Thu, 24 Aug 2023 19:11:55 -0400 Subject: [PATCH] LU-13306 mgc: handle large NID formats For newer versions of Lustre the MGS can send mgs_nidtbl_entry containing NIDs of a larger format. Its also possible an old MGS will send NIDs of the previous size. We need to handle both cases. We reused the field of mcb_nm_cur_pass, which only is used for nodemap, of the struct mgs_config_body to send the NID size from the client to the MGS. Pre IPv6 clients will by default have a zero mcb_nm_cur_pass / mcb_nid_size. When mcb_nid_size is zero the the MGS will treat the client as pre-IPv6 and send small NID back to the client. This avoids needing to patch older clients. If the MGS is older then small size NIDs will be sent back which the new MGC layer can handle by converting those lnet_nid_t to struct lnet_nid. To handle this new code the "swab" of the entry is split into two parts. The "header" is "swab"ed as soon as we know the entry is large enough for that to make sense. The content containing NID information is swabbed later once the header has been found to look sane. Test-Parameters: serverversion=2.15 testlist=runtests,sanity,recovery-small Change-Id: I97ebdcecc1ee0fbfe676cbdbdc77edee13e60891 Signed-off-by: James Simmons Signed-off-by: Mr NeilBrown Reviewed-on: https://review.whamcloud.com/c/fs/lustre-release/+/50750 Tested-by: jenkins Tested-by: Maloo Reviewed-by: Sebastien Buisson Reviewed-by: Oleg Drokin Reviewed-by: Andreas Dilger --- lustre/include/lustre_net.h | 8 +- lustre/include/lustre_swab.h | 3 +- lustre/include/obd_class.h | 4 +- lustre/include/uapi/linux/lustre/lustre_idl.h | 28 +++-- lustre/ldlm/ldlm_lib.c | 25 ++-- lustre/mgc/mgc_request.c | 166 +++++++++++++++++--------- lustre/mgs/mgs_nids.c | 70 +++++++---- lustre/obdclass/lustre_peer.c | 18 ++- lustre/ptlrpc/pack_generic.c | 32 +++-- lustre/ptlrpc/wiretest.c | 8 ++ lustre/utils/wirecheck.c | 2 + lustre/utils/wiretest.c | 8 ++ 12 files changed, 240 insertions(+), 132 deletions(-) diff --git a/lustre/include/lustre_net.h b/lustre/include/lustre_net.h index f1ec613..badba82 100644 --- a/lustre/include/lustre_net.h +++ b/lustre/include/lustre_net.h @@ -2616,9 +2616,11 @@ int client_disconnect_export(struct obd_export *exp); int client_import_add_conn(struct obd_import *imp, struct obd_uuid *uuid, int priority); int client_import_dyn_add_conn(struct obd_import *imp, struct obd_uuid *uuid, - lnet_nid_t prim_nid, int priority); -int client_import_add_nids_to_conn(struct obd_import *imp, lnet_nid_t *nids, - int nid_count, struct obd_uuid *uuid); + struct lnet_nid *prim_nid, int priority); +int client_import_add_nids_to_conn(struct obd_import *imp, + struct lnet_nid *nidlist, + int nid_count, int nid_size, + struct obd_uuid *uuid); int client_import_del_conn(struct obd_import *imp, struct obd_uuid *uuid); int import_set_conn_priority(struct obd_import *imp, struct obd_uuid *uuid); void client_destroy_import(struct obd_import *imp); diff --git a/lustre/include/lustre_swab.h b/lustre/include/lustre_swab.h index 5c96906..8dafadd 100644 --- a/lustre/include/lustre_swab.h +++ b/lustre/include/lustre_swab.h @@ -93,7 +93,8 @@ void lustre_swab_ldlm_lock_desc(struct ldlm_lock_desc *l); void lustre_swab_ldlm_request(struct ldlm_request *rq); void lustre_swab_ldlm_reply(struct ldlm_reply *r); void lustre_swab_mgs_target_info(struct mgs_target_info *oinfo); -void lustre_swab_mgs_nidtbl_entry(struct mgs_nidtbl_entry *oinfo); +void lustre_swab_mgs_nidtbl_entry_header(struct mgs_nidtbl_entry *oinfo); +void lustre_swab_mgs_nidtbl_entry_content(struct mgs_nidtbl_entry *oinfo); void lustre_swab_mgs_config_body(struct mgs_config_body *body); void lustre_swab_mgs_config_res(struct mgs_config_res *body); void lustre_swab_lfsck_request(struct lfsck_request *lr); diff --git a/lustre/include/obd_class.h b/lustre/include/obd_class.h index 0079ae4..cef3782 100644 --- a/lustre/include/obd_class.h +++ b/lustre/include/obd_class.h @@ -1974,8 +1974,8 @@ int lustre_uuid_to_peer(const char *uuid, struct lnet_nid *peer_nid, int index); int class_add_uuid(const char *uuid, struct lnet_nid *nid); int class_del_uuid (const char *uuid); -int class_add_nids_to_uuid(struct obd_uuid *uuid, lnet_nid_t *nids, - int nid_count); +int class_add_nids_to_uuid(struct obd_uuid *uuid, struct lnet_nid *nidlist, + int nid_count, int nid_size); int class_check_uuid(struct obd_uuid *uuid, struct lnet_nid *nid); /* class_obd.c */ diff --git a/lustre/include/uapi/linux/lustre/lustre_idl.h b/lustre/include/uapi/linux/lustre/lustre_idl.h index 887ba49..6157643 100644 --- a/lustre/include/uapi/linux/lustre/lustre_idl.h +++ b/lustre/include/uapi/linux/lustre/lustre_idl.h @@ -2637,17 +2637,18 @@ struct mgs_target_info { } __attribute__((packed)); struct mgs_nidtbl_entry { - __u64 mne_version; /* table version of this entry */ - __u32 mne_instance; /* target instance # */ - __u32 mne_index; /* target index */ - __u32 mne_length; /* length of this entry - by bytes */ - __u8 mne_type; /* target type LDD_F_SV_TYPE_OST/MDT */ - __u8 mne_nid_type; /* type of nid(mbz). for ipv6. */ - __u8 mne_nid_size; /* size of each NID, by bytes */ - __u8 mne_nid_count; /* # of NIDs in buffer */ - union { - lnet_nid_t nids[0]; /* variable size buffer for NIDs. */ - } u; + __u64 mne_version; /* table version of this entry */ + __u32 mne_instance; /* target instance # */ + __u32 mne_index; /* target index */ + __u32 mne_length; /* length of this entry - by bytes */ + __u8 mne_type; /* target type LDD_F_SV_TYPE_OST/MDT */ + __u8 mne_nid_type; /* type of NID. for IPv6. */ + __u8 mne_nid_size; /* size of each NID, by bytes */ + __u8 mne_nid_count; /* # of NIDs in buffer */ + union { + lnet_nid_t nids[0]; /* variable size buffer for NIDs. */ + struct lnet_nid nidlist[0]; + } u; }; enum mgs_cfg_type { @@ -2664,7 +2665,10 @@ struct mgs_config_body { char mcb_name[MTI_NAME_MAXLEN]; /* logname */ __u64 mcb_offset; /* next index of config log to request */ __u16 mcb_type; /* type of log: MGS_CFG_T_[CONFIG|RECOVER] */ - __u8 mcb_nm_cur_pass; + union { + __u8 mcb_nm_cur_pass; /* mcb_type == MGS_CFG_T_NODEMAP */ + __u8 mcb_rec_nid_size; /* mcb_type == MGS_CFG_T_RECOVER */ + }; __u8 mcb_bits; /* bits unit size of config log */ __u32 mcb_units; /* # of units for bulk transfer */ }; diff --git a/lustre/ldlm/ldlm_lib.c b/lustre/ldlm/ldlm_lib.c index 4c0d616..6069fa3 100644 --- a/lustre/ldlm/ldlm_lib.c +++ b/lustre/ldlm/ldlm_lib.c @@ -145,18 +145,16 @@ int client_import_add_conn(struct obd_import *imp, struct obd_uuid *uuid, EXPORT_SYMBOL(client_import_add_conn); int client_import_dyn_add_conn(struct obd_import *imp, struct obd_uuid *uuid, - lnet_nid_t prim_nid4, int priority) + struct lnet_nid *prim_nid, int priority) { struct ptlrpc_connection *ptlrpc_conn; - struct lnet_nid prim_nid; int rc; - lnet_nid4_to_nid(prim_nid4, &prim_nid); - ptlrpc_conn = ptlrpc_uuid_to_connection(uuid, LNET_NID_NET(&prim_nid)); + ptlrpc_conn = ptlrpc_uuid_to_connection(uuid, LNET_NID_NET(prim_nid)); if (!ptlrpc_conn) { const char *str_uuid = obd_uuid2str(uuid); - rc = class_add_uuid(str_uuid, &prim_nid); + rc = class_add_uuid(str_uuid, prim_nid); if (rc) { CERROR("%s: failed to add UUID '%s': rc = %d\n", imp->imp_obd->obd_name, str_uuid, rc); @@ -167,26 +165,25 @@ int client_import_dyn_add_conn(struct obd_import *imp, struct obd_uuid *uuid, } EXPORT_SYMBOL(client_import_dyn_add_conn); -int client_import_add_nids_to_conn(struct obd_import *imp, lnet_nid_t *nids, - int nid_count, struct obd_uuid *uuid) +int client_import_add_nids_to_conn(struct obd_import *imp, + struct lnet_nid *nidlist, + int nid_count, int nid_size, + struct obd_uuid *uuid) { struct obd_import_conn *conn; int rc = -ENOENT; ENTRY; - if (nid_count <= 0 || !nids) + if (nid_count <= 0 || !nidlist) return rc; spin_lock(&imp->imp_lock); list_for_each_entry(conn, &imp->imp_conn_list, oic_item) { - struct lnet_nid nid; - - lnet_nid4_to_nid(nids[0], &nid); - if (class_check_uuid(&conn->oic_uuid, &nid)) { + if (class_check_uuid(&conn->oic_uuid, &nidlist[0])) { *uuid = conn->oic_uuid; spin_unlock(&imp->imp_lock); - rc = class_add_nids_to_uuid(&conn->oic_uuid, nids, - nid_count); + rc = class_add_nids_to_uuid(&conn->oic_uuid, nidlist, + nid_count, nid_size); RETURN(rc); } } diff --git a/lustre/mgc/mgc_request.c b/lustre/mgc/mgc_request.c index 3827305..134a40e 100644 --- a/lustre/mgc/mgc_request.c +++ b/lustre/mgc/mgc_request.c @@ -1169,7 +1169,6 @@ static int mgc_apply_recover_logs(struct obd_device *mgc, void *data, int datalen, bool mne_swab) { struct config_llog_instance *cfg = &cld->cld_cfg; - struct mgs_nidtbl_entry *entry; struct lustre_cfg *lcfg; struct lustre_cfg_bufs bufs; u64 prev_version = 0; @@ -1211,45 +1210,50 @@ static int mgc_apply_recover_logs(struct obd_device *mgc, pos = 0; while (datalen > 0) { - int entry_len = sizeof(*entry); - int is_ost; + struct mgs_nidtbl_entry *entry = (data + off); + struct lnet_nid *nidlist = NULL; + int entry_len = sizeof(*entry); struct obd_device *obd; struct obd_import *imp; + struct obd_uuid *uuid; char *obdname; char *cname; char *params; - char *uuid; + bool is_ost; rc = -EINVAL; - if (datalen < sizeof(*entry)) + /* sanity checks */ + if (datalen < entry_len) /* really short on data */ break; - entry = (typeof(entry))(data + off); + /* swab non nid data */ + if (mne_swab) + lustre_swab_mgs_nidtbl_entry_header(entry); - /* sanity check */ - if (entry->mne_nid_type != 0) /* only support type 0 for ipv4 */ - break; if (entry->mne_nid_count == 0) /* at least one nid entry */ break; - if (entry->mne_nid_size != sizeof(lnet_nid_t)) - break; entry_len += entry->mne_nid_count * entry->mne_nid_size; if (datalen < entry_len) /* must have entry_len at least */ break; - /* Keep this swab for normal mixed endian handling. LU-1644 */ - if (mne_swab) - lustre_swab_mgs_nidtbl_entry(entry); if (entry->mne_length > PAGE_SIZE) { CERROR("MNE too large (%u)\n", entry->mne_length); break; } + /* improper mne_lenth */ if (entry->mne_length < entry_len) break; - off += entry->mne_length; + /* entry length reports larger than all the data passed in */ + if (datalen < entry->mne_length) + break; + + /* Looks sane - see if we can process this entry. + * If not, we continue to the next entry. + */ + off += entry->mne_length; datalen -= entry->mne_length; if (datalen < 0) break; @@ -1267,11 +1271,43 @@ static int mgc_apply_recover_logs(struct obd_device *mgc, } prev_version = entry->mne_version; + if (entry->mne_nid_type == 0) { + struct lnet_nid *nid; + int i; + + OBD_ALLOC_PTR_ARRAY(nidlist, entry->mne_nid_count); + if (!nidlist) { + rc = -ENOMEM; + break; + } + + /* Keep this nid data swab for normal mixed + * endian handling. LU-1644 + */ + if (mne_swab) + lustre_swab_mgs_nidtbl_entry_content(entry); + + /* Turn old NID format to newer format. */ + nid = nidlist; + for (i = 0; i < entry->mne_nid_count; i++) { + lnet_nid4_to_nid(entry->u.nids[i], nid); + nid += sizeof(struct lnet_nid); + } + } else { + /* Handle the case if struct lnet_nid is expanded in + * the future. The MGS should prevent this but just + * in case. + */ + if (entry->mne_nid_size > sizeof(struct lnet_nid)) + continue; + + nidlist = entry->u.nidlist; + } + /* * Write a string with format "nid::instance" to * lustre//--/import. */ - is_ost = entry->mne_type == LDD_F_SV_TYPE_OST; memset(buf, 0, bufsz); obdname = buf; @@ -1309,66 +1345,73 @@ static int mgc_apply_recover_logs(struct obd_device *mgc, ++pos; params = buf + pos; pos += sprintf(params, "%s.import=%s", cname, "connection="); - uuid = buf + pos; + uuid = (struct obd_uuid *)(buf + pos); with_imp_locked(obd, imp, rc) { + struct obd_uuid server_uuid; + char *primary_nid; + int prim_nid_len; + /* iterate all nids to find one */ /* find uuid by nid */ /* create import entries if they don't exist */ - rc = client_import_add_nids_to_conn( - imp, entry->u.nids, entry->mne_nid_count, - (struct obd_uuid *)uuid); - - if (rc == -ENOENT && dynamic_nids) { - /* create a new connection for this import */ - char *primary_nid = - libcfs_nid2str(entry->u.nids[0]); - int prim_nid_len = strlen(primary_nid) + 1; - struct obd_uuid server_uuid; - - if (prim_nid_len > UUID_MAX) - goto fail; - strncpy(server_uuid.uuid, primary_nid, - prim_nid_len); - - CDEBUG(D_INFO, "Adding a connection for %s\n", - primary_nid); - - rc = client_import_dyn_add_conn( - imp, &server_uuid, entry->u.nids[0], 1); - if (rc < 0) { - CERROR("%s: Failed to add new connection with NID '%s' to import: rc = %d\n", - obd->obd_name, primary_nid, rc); - goto fail; - } - rc = client_import_add_nids_to_conn( - imp, entry->u.nids, - entry->mne_nid_count, - (struct obd_uuid *)uuid); - if (rc < 0) { - CERROR("%s: failed to lookup UUID: rc = %d\n", - obd->obd_name, rc); - goto fail; - } + rc = client_import_add_nids_to_conn(imp, nidlist, + entry->mne_nid_count, + entry->mne_nid_size, + uuid); + if (rc != -ENOENT || !dynamic_nids) + continue; + + /* create a new connection for this import */ + primary_nid = libcfs_nidstr(&nidlist[0]); + prim_nid_len = strlen(primary_nid) + 1; + if (prim_nid_len > UUID_MAX) + goto fail; + + strncpy(server_uuid.uuid, primary_nid, + prim_nid_len); + + CDEBUG(D_INFO, "Adding a connection for %s\n", + primary_nid); + + rc = client_import_dyn_add_conn(imp, &server_uuid, + &nidlist[0], 1); + if (rc < 0) { + CERROR("%s: Failed to add new connection with NID '%s' to import: rc = %d\n", + obd->obd_name, primary_nid, rc); + goto fail; } + + rc = client_import_add_nids_to_conn(imp, nidlist, + entry->mne_nid_count, + entry->mne_nid_size, + uuid); + if (rc < 0) + CERROR("%s: failed to lookup UUID: rc = %d\n", + obd->obd_name, rc); fail:; } + if (rc == -ENODEV) { /* client does not connect to the OST yet */ rc = 0; - continue; + goto free_nids; } if (rc < 0 && rc != -ENOSPC) { CERROR("mgc: cannot find UUID by nid '%s': rc = %d\n", - libcfs_nid2str(entry->u.nids[0]), rc); + libcfs_nidstr(&nidlist[0]), rc); + + /* For old NID format case the nidlist was allocated. */ + if (entry->mne_nid_type == 0) + OBD_FREE_PTR_ARRAY(nidlist, entry->mne_nid_count); break; } CDEBUG(D_INFO, "Found UUID '%s' by NID '%s'\n", - uuid, libcfs_nid2str(entry->u.nids[0])); + uuid->uuid, libcfs_nidstr(&nidlist[0])); - pos += strlen(uuid); + pos += strlen(uuid->uuid); pos += sprintf(buf + pos, "::%u", entry->mne_instance); LASSERT(pos < bufsz); @@ -1393,6 +1436,10 @@ fail:; obdname, rc); /* continue, even one with error */ +free_nids: + /* For old NID format case the nidlist was allocated. */ + if (entry->mne_nid_type == 0) + OBD_FREE_PTR_ARRAY(nidlist, entry->mne_nid_count); } OBD_FREE(buf, PAGE_SIZE); @@ -1463,9 +1510,10 @@ again: >= sizeof(body->mcb_name)) GOTO(out, rc = -E2BIG); body->mcb_offset = cfg->cfg_last_idx + 1; - body->mcb_type = cld->cld_type; - body->mcb_bits = PAGE_SHIFT; - body->mcb_units = nrpages; + body->mcb_type = cld->cld_type; + body->mcb_bits = PAGE_SHIFT; + body->mcb_units = nrpages; + body->mcb_rec_nid_size = sizeof(struct lnet_nid); /* allocate bulk transfer descriptor */ desc = ptlrpc_prep_bulk_imp(req, nrpages, 1, diff --git a/lustre/mgs/mgs_nids.c b/lustre/mgs/mgs_nids.c index 969e06a..04f1629 100644 --- a/lustre/mgs/mgs_nids.c +++ b/lustre/mgs/mgs_nids.c @@ -73,8 +73,9 @@ static int nidtbl_is_sane(struct mgs_nidtbl *tbl) * shouldn't cross unit boundaries. */ static int mgs_nidtbl_read(struct obd_export *exp, struct mgs_nidtbl *tbl, - struct mgs_config_res *res, struct page **pages, - int nrpages, int units_total, int unit_size) + struct mgs_config_res *res, u8 nid_size, + struct page **pages, int nrpages, + int units_total, int unit_size) { struct mgs_nidtbl_target *tgt; struct mgs_nidtbl_entry *entry; @@ -118,9 +119,10 @@ static int mgs_nidtbl_read(struct obd_export *exp, struct mgs_nidtbl *tbl, /* write target recover information */ mti = &tgt->mnt_mti; - if (!target_supports_large_nid(mti)) - LASSERT(mti->mti_nid_count < MTI_NIDS_MAX); - entry_len += mti->mti_nid_count * sizeof(lnet_nid_t); + if (!nid_size) + entry_len += mti->mti_nid_count * sizeof(lnet_nid_t); + else + entry_len += mti->mti_nid_count * nid_size; if (entry_len > unit_size) { CWARN("nidtbl: too large entry: entry length %d, unit size: %d\n", @@ -172,20 +174,24 @@ static int mgs_nidtbl_read(struct obd_export *exp, struct mgs_nidtbl *tbl, /* fill in entry. */ entry = (struct mgs_nidtbl_entry *)buf; - entry->mne_version = tgt->mnt_version; - entry->mne_instance = mti->mti_instance; - entry->mne_index = mti->mti_stripe_index; - entry->mne_length = entry_len; - entry->mne_type = tgt->mnt_type; - entry->mne_nid_type = 0; - entry->mne_nid_size = sizeof(lnet_nid_t); + entry->mne_version = tgt->mnt_version; + entry->mne_instance = mti->mti_instance; + entry->mne_index = mti->mti_stripe_index; + entry->mne_length = entry_len; + entry->mne_type = tgt->mnt_type; + if (nid_size) { + entry->mne_nid_size = nid_size; + entry->mne_nid_type = 1; + } else { + entry->mne_nid_size = sizeof(lnet_nid_t); + entry->mne_nid_type = 0; + } + entry->mne_nid_count = 0; /* We have been sent the newer larger NID format but the * current nidtbl doesn't support it. So filter the NIDs * sent to reject any real larger size NIDS. */ if (target_supports_large_nid(mti)) { - entry->mne_nid_count = 0; - for (i = 0; i < mti->mti_nid_count; i++) { struct lnet_nid nid; int err; @@ -194,20 +200,37 @@ static int mgs_nidtbl_read(struct obd_export *exp, struct mgs_nidtbl *tbl, if (err < 0) GOTO(out, rc = err); - /* if the large NID format represents a small - * address space we can still pass it back to - * the older clients. - */ - if (nid_is_nid4(&nid)) { + if (nid_size == 0) { + if (!nid_is_nid4(&nid)) + continue; + entry->u.nids[entry->mne_nid_count] = lnet_nid_to_nid4(&nid); - entry->mne_nid_count++; + } else { + /* If the mgs_target_info NIDs are + * struct lnet_nid that have been + * expanded in size we still can + * use the nid if it fits in what + * the client supports. + */ + if (NID_BYTES(&nid) > nid_size) + continue; + + entry->u.nidlist[entry->mne_nid_count] = + nid; } + entry->mne_nid_count++; } } else { + if (nid_size) { + for (i = 0; i < mti->mti_nid_count; i++) + lnet_nid4_to_nid(mti->mti_nids[i], + &entry->u.nidlist[i]); + } else { + memcpy(entry->u.nids, mti->mti_nids, + mti->mti_nid_count * sizeof(lnet_nid_t)); + } entry->mne_nid_count = mti->mti_nid_count; - memcpy(entry->u.nids, mti->mti_nids, - mti->mti_nid_count * sizeof(lnet_nid_t)); } version = tgt->mnt_version; @@ -689,7 +712,8 @@ int mgs_get_ir_logs(struct ptlrpc_request *req) res->mcr_offset = body->mcb_offset; unit_size = min_t(int, 1 << body->mcb_bits, PAGE_SIZE); bytes = mgs_nidtbl_read(req->rq_export, &fsdb->fsdb_nidtbl, res, - pages, nrpages, bufsize / unit_size, unit_size); + body->mcb_rec_nid_size, pages, nrpages, + bufsize / unit_size, unit_size); if (bytes < 0) GOTO(out, rc = bytes); diff --git a/lustre/obdclass/lustre_peer.c b/lustre/obdclass/lustre_peer.c index 8b47ccb..f8db9fc 100644 --- a/lustre/obdclass/lustre_peer.c +++ b/lustre/obdclass/lustre_peer.c @@ -173,8 +173,8 @@ int class_del_uuid(const char *uuid) return 0; } -int class_add_nids_to_uuid(struct obd_uuid *uuid, lnet_nid_t *nids, - int nid_count) +int class_add_nids_to_uuid(struct obd_uuid *uuid, struct lnet_nid *nidlist, + int nid_count, int nid_size) { struct uuid_nid_data *entry; int i, rc; @@ -197,10 +197,18 @@ int class_add_nids_to_uuid(struct obd_uuid *uuid, lnet_nid_t *nids, continue; matched = true; + entry->un_nid_count = 0; CDEBUG(D_NET, "Updating UUID '%s'\n", obd_uuid2str(uuid)); - for (i = 0; i < nid_count; i++) - lnet_nid4_to_nid(nids[i], &entry->un_nids[i]); - entry->un_nid_count = nid_count; + for (i = 0; i < nid_count; i++) { + if (NID_BYTES(&nidlist[i]) > nid_size) + continue; + + entry->un_nid_count++; + memset(&entry->un_nids[entry->un_nid_count], 0, + sizeof(entry->un_nids[entry->un_nid_count])); + memcpy(&entry->un_nids[entry->un_nid_count], + &nidlist[i], nid_size); + } break; } spin_unlock(&g_uuid_lock); diff --git a/lustre/ptlrpc/pack_generic.c b/lustre/ptlrpc/pack_generic.c index 61e4b18..b9c77c6 100644 --- a/lustre/ptlrpc/pack_generic.c +++ b/lustre/ptlrpc/pack_generic.c @@ -2087,28 +2087,34 @@ void lustre_swab_mgs_target_info(struct mgs_target_info *mti) __swab64s(&mti->mti_nids[i]); } -void lustre_swab_mgs_nidtbl_entry(struct mgs_nidtbl_entry *entry) +void lustre_swab_mgs_nidtbl_entry_header(struct mgs_nidtbl_entry *entry) { - __u8 i; - __swab64s(&entry->mne_version); __swab32s(&entry->mne_instance); __swab32s(&entry->mne_index); __swab32s(&entry->mne_length); - /* mne_nid_(count|type) must be one byte size because we're gonna - * access it w/o swapping. */ - BUILD_BUG_ON(sizeof(entry->mne_nid_count) != sizeof(__u8)); - BUILD_BUG_ON(sizeof(entry->mne_nid_type) != sizeof(__u8)); + /* mne_nid_(count|type) must be one byte size because we're going to + * access it w/o swapping. + */ + BUILD_BUG_ON(sizeof(entry->mne_nid_count) != sizeof(u8)); + BUILD_BUG_ON(sizeof(entry->mne_nid_type) != sizeof(u8)); + +} +EXPORT_SYMBOL(lustre_swab_mgs_nidtbl_entry_header); + +void lustre_swab_mgs_nidtbl_entry_content(struct mgs_nidtbl_entry *entry) +{ + int i; - /* remove this assertion if ipv6 is supported. */ - LASSERT(entry->mne_nid_type == 0); - for (i = 0; i < entry->mne_nid_count; i++) { - BUILD_BUG_ON(sizeof(lnet_nid_t) != sizeof(__u64)); + /* Large NIDs are always big endian so we don't need swapping */ + if (entry->mne_nid_type) + return; + + for (i = 0; i < entry->mne_nid_count; i++) __swab64s(&entry->u.nids[i]); - } } -EXPORT_SYMBOL(lustre_swab_mgs_nidtbl_entry); +EXPORT_SYMBOL(lustre_swab_mgs_nidtbl_entry_content); void lustre_swab_mgs_config_body(struct mgs_config_body *body) { diff --git a/lustre/ptlrpc/wiretest.c b/lustre/ptlrpc/wiretest.c index 172903f..5b5a1d5 100644 --- a/lustre/ptlrpc/wiretest.c +++ b/lustre/ptlrpc/wiretest.c @@ -4686,6 +4686,10 @@ void lustre_assert_wire_constants(void) (long long)(int)offsetof(struct mgs_nidtbl_entry, u.nids[0])); LASSERTF((int)sizeof(((struct mgs_nidtbl_entry *)0)->u.nids[0]) == 8, "found %lld\n", (long long)(int)sizeof(((struct mgs_nidtbl_entry *)0)->u.nids[0])); + LASSERTF((int)offsetof(struct mgs_nidtbl_entry, u.nidlist[0]) == 24, "found %lld\n", + (long long)(int)offsetof(struct mgs_nidtbl_entry, u.nidlist[0])); + LASSERTF((int)sizeof(((struct mgs_nidtbl_entry *)0)->u.nidlist[0]) == 20, "found %lld\n", + (long long)(int)sizeof(((struct mgs_nidtbl_entry *)0)->u.nidlist[0])); /* Checks for struct mgs_config_body */ LASSERTF((int)sizeof(struct mgs_config_body) == 80, "found %lld\n", @@ -4706,6 +4710,10 @@ void lustre_assert_wire_constants(void) (long long)(int)offsetof(struct mgs_config_body, mcb_nm_cur_pass)); LASSERTF((int)sizeof(((struct mgs_config_body *)0)->mcb_nm_cur_pass) == 1, "found %lld\n", (long long)(int)sizeof(((struct mgs_config_body *)0)->mcb_nm_cur_pass)); + LASSERTF((int)offsetof(struct mgs_config_body, mcb_rec_nid_size) == 74, "found %lld\n", + (long long)(int)offsetof(struct mgs_config_body, mcb_rec_nid_size)); + LASSERTF((int)sizeof(((struct mgs_config_body *)0)->mcb_rec_nid_size) == 1, "found %lld\n", + (long long)(int)sizeof(((struct mgs_config_body *)0)->mcb_rec_nid_size)); LASSERTF((int)offsetof(struct mgs_config_body, mcb_bits) == 75, "found %lld\n", (long long)(int)offsetof(struct mgs_config_body, mcb_bits)); LASSERTF((int)sizeof(((struct mgs_config_body *)0)->mcb_bits) == 1, "found %lld\n", diff --git a/lustre/utils/wirecheck.c b/lustre/utils/wirecheck.c index 614e768..0b9a7e9 100644 --- a/lustre/utils/wirecheck.c +++ b/lustre/utils/wirecheck.c @@ -2177,6 +2177,7 @@ check_mgs_nidtbl_entry(void) CHECK_MEMBER(mgs_nidtbl_entry, mne_nid_size); CHECK_MEMBER(mgs_nidtbl_entry, mne_nid_count); CHECK_MEMBER(mgs_nidtbl_entry, u.nids[0]); + CHECK_MEMBER(mgs_nidtbl_entry, u.nidlist[0]); } static void @@ -2188,6 +2189,7 @@ check_mgs_config_body(void) CHECK_MEMBER(mgs_config_body, mcb_offset); CHECK_MEMBER(mgs_config_body, mcb_type); CHECK_MEMBER(mgs_config_body, mcb_nm_cur_pass); + CHECK_MEMBER(mgs_config_body, mcb_rec_nid_size); CHECK_MEMBER(mgs_config_body, mcb_bits); CHECK_MEMBER(mgs_config_body, mcb_units); diff --git a/lustre/utils/wiretest.c b/lustre/utils/wiretest.c index b475413..81739d4 100644 --- a/lustre/utils/wiretest.c +++ b/lustre/utils/wiretest.c @@ -4747,6 +4747,10 @@ void lustre_assert_wire_constants(void) (long long)(int)offsetof(struct mgs_nidtbl_entry, u.nids[0])); LASSERTF((int)sizeof(((struct mgs_nidtbl_entry *)0)->u.nids[0]) == 8, "found %lld\n", (long long)(int)sizeof(((struct mgs_nidtbl_entry *)0)->u.nids[0])); + LASSERTF((int)offsetof(struct mgs_nidtbl_entry, u.nidlist[0]) == 24, "found %lld\n", + (long long)(int)offsetof(struct mgs_nidtbl_entry, u.nidlist[0])); + LASSERTF((int)sizeof(((struct mgs_nidtbl_entry *)0)->u.nidlist[0]) == 20, "found %lld\n", + (long long)(int)sizeof(((struct mgs_nidtbl_entry *)0)->u.nidlist[0])); /* Checks for struct mgs_config_body */ LASSERTF((int)sizeof(struct mgs_config_body) == 80, "found %lld\n", @@ -4767,6 +4771,10 @@ void lustre_assert_wire_constants(void) (long long)(int)offsetof(struct mgs_config_body, mcb_nm_cur_pass)); LASSERTF((int)sizeof(((struct mgs_config_body *)0)->mcb_nm_cur_pass) == 1, "found %lld\n", (long long)(int)sizeof(((struct mgs_config_body *)0)->mcb_nm_cur_pass)); + LASSERTF((int)offsetof(struct mgs_config_body, mcb_rec_nid_size) == 74, "found %lld\n", + (long long)(int)offsetof(struct mgs_config_body, mcb_rec_nid_size)); + LASSERTF((int)sizeof(((struct mgs_config_body *)0)->mcb_rec_nid_size) == 1, "found %lld\n", + (long long)(int)sizeof(((struct mgs_config_body *)0)->mcb_rec_nid_size)); LASSERTF((int)offsetof(struct mgs_config_body, mcb_bits) == 75, "found %lld\n", (long long)(int)offsetof(struct mgs_config_body, mcb_bits)); LASSERTF((int)sizeof(((struct mgs_config_body *)0)->mcb_bits) == 1, "found %lld\n", -- 1.8.3.1