X-Git-Url: https://git.whamcloud.com/?a=blobdiff_plain;f=lustre%2Fobdclass%2Fkernelcomm.c;h=7afb9484a8a69855dfc9adb291d3a1d9f7a310ed;hb=01261e7b563adc97899d962f0ba2d1b430894bf7;hp=9e4b84c7e8d5e7cf763b77d6a6cd0bcf174d0a31;hpb=37bbe9a1bf33b77d3f239ea69ce052e99f09308d;p=fs%2Flustre-release.git diff --git a/lustre/obdclass/kernelcomm.c b/lustre/obdclass/kernelcomm.c index 9e4b84c..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/ @@ -35,35 +35,12 @@ */ #define DEBUG_SUBSYSTEM S_CLASS -#define D_KUC D_OTHER + +#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 @@ -73,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) { @@ -84,11 +62,19 @@ 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 - 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; } @@ -100,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]; @@ -128,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; @@ -143,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); @@ -155,13 +143,13 @@ int libcfs_kkuc_group_add(struct file *filp, int uid, int 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; } 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; @@ -179,14 +167,15 @@ 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_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); @@ -199,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; @@ -221,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; @@ -248,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; @@ -262,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);