X-Git-Url: https://git.whamcloud.com/?a=blobdiff_plain;f=lustre%2Fobdclass%2Fkernelcomm.c;h=ccd982c2805e2a236736824327057709e647bf84;hb=8c3c81fb787ab0a0152ebf497d1b4aef480bb82f;hp=f178ebc9e02faf3faa3150370975132e55951316;hpb=7f67aa42f9123caef3cee714f1e2cee3c6848892;p=fs%2Flustre-release.git diff --git a/lustre/obdclass/kernelcomm.c b/lustre/obdclass/kernelcomm.c index f178ebc..ccd982c 100644 --- a/lustre/obdclass/kernelcomm.c +++ b/lustre/obdclass/kernelcomm.c @@ -23,7 +23,7 @@ * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved. * Use is subject to license terms. * - * Copyright (c) 2012, 2013, Intel Corporation. + * Copyright (c) 2015, Intel Corporation. */ /* * This file is part of Lustre, http://www.lustre.org/ @@ -35,7 +35,6 @@ */ #define DEBUG_SUBSYSTEM S_CLASS -#define D_KUC D_OTHER #include #include @@ -88,7 +87,7 @@ int libcfs_kkuc_msg_put(struct file *filp, void *payload) if (rc < 0) CWARN("message send failed (%d)\n", rc); else - CDEBUG(D_KUC, "Sent message rc=%d, fp=%p\n", rc, filp); + CDEBUG(D_HSM, "Sent message rc=%d, fp=%p\n", rc, filp); return rc; } @@ -105,10 +104,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 +132,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,12 +151,10 @@ 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); - CDEBUG(D_KUC, "Added uid=%d fp=%p to group %d\n", uid, filp, group); + CDEBUG(D_HSM, "Added uid=%d fp=%p to group %d\n", uid, filp, group); return 0; } @@ -155,8 +165,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 */ @@ -173,7 +185,7 @@ int libcfs_kkuc_group_rem(int uid, int group) list_for_each_entry_safe(reg, next, &kkuc_groups[group], kr_chain) { if ((uid == 0) || (uid == reg->kr_uid)) { list_del(®->kr_chain); - CDEBUG(D_KUC, "Removed uid=%d fp=%p from group %d\n", + CDEBUG(D_HSM, "Removed uid=%d fp=%p from group %d\n", reg->kr_uid, reg->kr_fp, group); if (reg->kr_fp != NULL) fput(reg->kr_fp); @@ -193,7 +205,20 @@ 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(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); + RETURN(-EAGAIN); + } + list_for_each_entry(reg, &kkuc_groups[group], kr_chain) { if (reg->kr_fp != NULL) { rc = libcfs_kkuc_msg_put(reg->kr_fp, payload); @@ -229,15 +254,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)