X-Git-Url: https://git.whamcloud.com/?a=blobdiff_plain;f=lustre%2Fobdclass%2Fkernelcomm.c;h=7afb9484a8a69855dfc9adb291d3a1d9f7a310ed;hb=449c648793d2fc4e8eee3a2dd918379b75cc81e2;hp=ccd982c2805e2a236736824327057709e647bf84;hpb=8c3c81fb787ab0a0152ebf497d1b4aef480bb82f;p=fs%2Flustre-release.git diff --git a/lustre/obdclass/kernelcomm.c b/lustre/obdclass/kernelcomm.c index ccd982c..7afb948 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) 2015, Intel Corporation. + * Copyright (c) 2015, 2017, Intel Corporation. */ /* * This file is part of Lustre, http://www.lustre.org/ @@ -36,33 +36,11 @@ #define DEBUG_SUBSYSTEM S_CLASS +#include + #include #include -/* write a userspace buffer to disk. - * NOTE: this returns 0 on success, not the number of bytes written. */ -static ssize_t -filp_user_write(struct file *filp, const void *buf, size_t count, - loff_t *offset) -{ - mm_segment_t fs; - ssize_t size = 0; - - fs = get_fs(); - set_fs(KERNEL_DS); - while ((ssize_t)count > 0) { - size = vfs_write(filp, (const void __user *)buf, count, offset); - if (size < 0) - break; - count -= size; - buf += size; - size = 0; - } - set_fs(fs); - - return size; -} - /** * libcfs_kkuc_msg_put - send an message from kernel to userspace * @param fp to send the message to @@ -72,10 +50,11 @@ filp_user_write(struct file *filp, const void *buf, size_t count, int libcfs_kkuc_msg_put(struct file *filp, void *payload) { struct kuc_hdr *kuch = (struct kuc_hdr *)payload; - int rc = -ENOSYS; + ssize_t count = kuch->kuc_msglen; loff_t offset = 0; + int rc = 0; - if (filp == NULL || IS_ERR(filp)) + if (IS_ERR_OR_NULL(filp)) return -EBADF; if (kuch->kuc_magic != KUC_MAGIC) { @@ -83,7 +62,15 @@ int libcfs_kkuc_msg_put(struct file *filp, void *payload) return -ENOSYS; } - rc = filp_user_write(filp, payload, kuch->kuc_msglen, &offset); + while (count > 0) { + rc = cfs_kernel_write(filp, payload, count, &offset); + if (rc < 0) + break; + count -= rc; + payload += rc; + rc = 0; + } + if (rc < 0) CWARN("message send failed (%d)\n", rc); else @@ -99,6 +86,7 @@ EXPORT_SYMBOL(libcfs_kkuc_msg_put); /** A single group registration has a uid and a file pointer */ struct kkuc_reg { struct list_head kr_chain; + struct obd_uuid kr_uuid; int kr_uid; struct file *kr_fp; char kr_data[0]; @@ -127,8 +115,8 @@ void libcfs_kkuc_init(void) * @param group group number * @param data user data */ -int libcfs_kkuc_group_add(struct file *filp, int uid, int group, - void *data, size_t data_len) +int libcfs_kkuc_group_add(struct file *filp, const struct obd_uuid *uuid, + int uid, int group, void *data, size_t data_len) { struct kkuc_reg *reg; @@ -142,10 +130,11 @@ int libcfs_kkuc_group_add(struct file *filp, int uid, int group, return -EBADF; /* freed in group_rem */ - reg = kmalloc(sizeof(*reg) + data_len, 0); + reg = kzalloc(sizeof(*reg) + data_len, 0); if (reg == NULL) return -ENOMEM; + reg->kr_uuid = *uuid; reg->kr_fp = filp; reg->kr_uid = uid; memcpy(reg->kr_data, data, data_len); @@ -160,7 +149,7 @@ int libcfs_kkuc_group_add(struct file *filp, int uid, int group, } EXPORT_SYMBOL(libcfs_kkuc_group_add); -int libcfs_kkuc_group_rem(int uid, int group) +int libcfs_kkuc_group_rem(const struct obd_uuid *uuid, int uid, int group) { struct kkuc_reg *reg, *next; ENTRY; @@ -178,12 +167,13 @@ int libcfs_kkuc_group_rem(int uid, int group) lh.kuc_transport = KUC_TRANSPORT_GENERIC; lh.kuc_msgtype = KUC_MSG_SHUTDOWN; lh.kuc_msglen = sizeof(lh); - libcfs_kkuc_group_put(group, &lh); + libcfs_kkuc_group_put(uuid, group, &lh); } down_write(&kg_sem); list_for_each_entry_safe(reg, next, &kkuc_groups[group], kr_chain) { - if ((uid == 0) || (uid == reg->kr_uid)) { + if (obd_uuid_equals(uuid, ®->kr_uuid) && + (uid == 0 || uid == reg->kr_uid)) { list_del(®->kr_chain); CDEBUG(D_HSM, "Removed uid=%d fp=%p from group %d\n", reg->kr_uid, reg->kr_fp, group); @@ -198,7 +188,7 @@ int libcfs_kkuc_group_rem(int uid, int group) } EXPORT_SYMBOL(libcfs_kkuc_group_rem); -int libcfs_kkuc_group_put(int group, void *payload) +int libcfs_kkuc_group_put(const struct obd_uuid *uuid, int group, void *payload) { struct kkuc_reg *reg; int rc = 0; @@ -220,7 +210,8 @@ int libcfs_kkuc_group_put(int group, void *payload) } list_for_each_entry(reg, &kkuc_groups[group], kr_chain) { - if (reg->kr_fp != NULL) { + if (obd_uuid_equals(uuid, ®->kr_uuid) && + reg->kr_fp != NULL) { rc = libcfs_kkuc_msg_put(reg->kr_fp, payload); if (rc == 0) one_success = 1; @@ -247,8 +238,8 @@ EXPORT_SYMBOL(libcfs_kkuc_group_put); * @param cb_func the function to be called. * @param cb_arg extra argument to be passed to the callback function. */ -int libcfs_kkuc_group_foreach(int group, libcfs_kkuc_cb_t cb_func, - void *cb_arg) +int libcfs_kkuc_group_foreach(const struct obd_uuid *uuid, int group, + libcfs_kkuc_cb_t cb_func, void *cb_arg) { struct kkuc_reg *reg; int rc = 0; @@ -261,7 +252,7 @@ int libcfs_kkuc_group_foreach(int group, libcfs_kkuc_cb_t cb_func, down_read(&kg_sem); list_for_each_entry(reg, &kkuc_groups[group], kr_chain) { - if (reg->kr_fp != NULL) + if (obd_uuid_equals(uuid, ®->kr_uuid) && reg->kr_fp != NULL) rc = cb_func(reg->kr_data, cb_arg); } up_read(&kg_sem);