From 37bbe9a1bf33b77d3f239ea69ce052e99f09308d Mon Sep 17 00:00:00 2001 From: "John L. Hammond" Date: Fri, 28 Apr 2017 10:12:01 -0500 Subject: [PATCH] LU-9306 kuc: initialize kkuc_groups at module init time Some kkuc functions use kkuc_groups[group].next == NULL to test for an empty group list. This is incorrect if the group was previously added to but not empty. Remove all next == NULL tests and use module load time initialization of the kkuc_groups array. Signed-off-by: John L. Hammond Change-Id: I0d6af7b8584f18d1dc03873993d6aac55b1677a9 Reviewed-on: https://review.whamcloud.com/26883 Tested-by: Jenkins Reviewed-by: Frank Zago Reviewed-by: Faccini Bruno Tested-by: Maloo Reviewed-by: Henri Doreau Reviewed-by: Quentin Bouget Reviewed-by: Oleg Drokin --- lustre/include/lustre_kernelcomm.h | 1 + lustre/obdclass/class_obd.c | 3 +++ lustre/obdclass/kernelcomm.c | 38 ++++++++++++++++++++++++++------------ 3 files changed, 30 insertions(+), 12 deletions(-) diff --git a/lustre/include/lustre_kernelcomm.h b/lustre/include/lustre_kernelcomm.h index 1d6efda..cb8a29f 100644 --- a/lustre/include/lustre_kernelcomm.h +++ b/lustre/include/lustre_kernelcomm.h @@ -44,6 +44,7 @@ typedef int (*libcfs_kkuc_cb_t)(void *data, void *cb_arg); /* Kernel methods */ +void libcfs_kkuc_init(void); int libcfs_kkuc_msg_put(struct file *fp, void *payload); int libcfs_kkuc_group_put(int group, void *payload); int libcfs_kkuc_group_add(struct file *fp, int uid, int group, diff --git a/lustre/obdclass/class_obd.c b/lustre/obdclass/class_obd.c index 75c5dab..17b0b9f 100644 --- a/lustre/obdclass/class_obd.c +++ b/lustre/obdclass/class_obd.c @@ -43,6 +43,7 @@ #include #include #include +#include #include #include #include @@ -492,6 +493,8 @@ static int __init obdclass_init(void) LCONSOLE_INFO("Lustre: Build Version: "LUSTRE_VERSION_STRING"\n"); + libcfs_kkuc_init(); + err = obd_init_checks(); if (err == -EOVERFLOW) return err; diff --git a/lustre/obdclass/kernelcomm.c b/lustre/obdclass/kernelcomm.c index cb52660..9e4b84c 100644 --- a/lustre/obdclass/kernelcomm.c +++ b/lustre/obdclass/kernelcomm.c @@ -105,10 +105,23 @@ struct kkuc_reg { char kr_data[0]; }; -static struct list_head kkuc_groups[KUC_GRP_MAX+1] = {}; +static struct list_head kkuc_groups[KUC_GRP_MAX + 1]; /* Protect message sending against remove and adds */ static DECLARE_RWSEM(kg_sem); +static inline bool libcfs_kkuc_group_is_valid(int group) +{ + return 0 <= group && group < ARRAY_SIZE(kkuc_groups); +} + +void libcfs_kkuc_init(void) +{ + int group; + + for (group = 0; group < ARRAY_SIZE(kkuc_groups); group++) + INIT_LIST_HEAD(&kkuc_groups[group]); +} + /** Add a receiver to a broadcast group * @param filp pipe to write into * @param uid identifier for this receiver @@ -120,7 +133,7 @@ int libcfs_kkuc_group_add(struct file *filp, int uid, int group, { struct kkuc_reg *reg; - if (group > KUC_GRP_MAX) { + if (!libcfs_kkuc_group_is_valid(group)) { CDEBUG(D_WARNING, "Kernelcomm: bad group %d\n", group); return -EINVAL; } @@ -139,8 +152,6 @@ int libcfs_kkuc_group_add(struct file *filp, int uid, int group, memcpy(reg->kr_data, data, data_len); down_write(&kg_sem); - if (kkuc_groups[group].next == NULL) - INIT_LIST_HEAD(&kkuc_groups[group]); list_add(®->kr_chain, &kkuc_groups[group]); up_write(&kg_sem); @@ -155,8 +166,10 @@ int libcfs_kkuc_group_rem(int uid, int group) struct kkuc_reg *reg, *next; ENTRY; - if (kkuc_groups[group].next == NULL) - RETURN(0); + if (!libcfs_kkuc_group_is_valid(group)) { + CDEBUG(D_WARNING, "Kernelcomm: bad group %d\n", group); + return -EINVAL; + } if (uid == 0) { /* Broadcast a shutdown message */ @@ -193,9 +206,14 @@ int libcfs_kkuc_group_put(int group, void *payload) int one_success = 0; ENTRY; + if (!libcfs_kkuc_group_is_valid(group)) { + CDEBUG(D_WARNING, "Kernelcomm: bad group %d\n", group); + return -EINVAL; + } + down_write(&kg_sem); - if (unlikely(kkuc_groups[group].next == NULL) || + if (unlikely(list_empty(&kkuc_groups[group])) || unlikely(OBD_FAIL_CHECK(OBD_FAIL_MDS_HSM_CT_REGISTER_NET))) { /* no agent have fully registered, CDT will retry */ up_write(&kg_sem); @@ -237,15 +255,11 @@ int libcfs_kkuc_group_foreach(int group, libcfs_kkuc_cb_t cb_func, int rc = 0; ENTRY; - if (group > KUC_GRP_MAX) { + if (!libcfs_kkuc_group_is_valid(group)) { CDEBUG(D_WARNING, "Kernelcomm: bad group %d\n", group); RETURN(-EINVAL); } - /* no link for this group */ - if (kkuc_groups[group].next == NULL) - RETURN(0); - down_read(&kg_sem); list_for_each_entry(reg, &kkuc_groups[group], kr_chain) { if (reg->kr_fp != NULL) -- 1.8.3.1