X-Git-Url: https://git.whamcloud.com/?a=blobdiff_plain;f=libcfs%2Flibcfs%2Fmodule.c;h=6170124bbf21deeedf109ca464657e46f9b09e67;hb=10ebe81e394af356fbae4703ca47586d6b3bc367;hp=ee678ec19db7e97760c1dad6074fe5bd8236e69c;hpb=c64a87cede3b070573ed0062d98fc33be34111b8;p=fs%2Flustre-release.git diff --git a/libcfs/libcfs/module.c b/libcfs/libcfs/module.c index ee678ec..6170124 100644 --- a/libcfs/libcfs/module.c +++ b/libcfs/libcfs/module.c @@ -27,7 +27,7 @@ * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved. * Use is subject to license terms. * - * Copyright (c) 2012, Intel Corporation. + * Copyright (c) 2012, 2014, Intel Corporation. */ /* * This file is part of Lustre, http://www.lustre.org/ @@ -35,18 +35,12 @@ */ #define DEBUG_SUBSYSTEM S_LNET -#define LNET_MAX_IOCTL_BUF_LEN (sizeof(struct lnet_ioctl_net_config) + \ - sizeof(struct lnet_ioctl_config_data)) #include #include #include -#include -#include -#include -#include "tracefile.h" -void +static void kportal_memhog_free (struct libcfs_device_userstate *ldu) { struct page **level0p = &ldu->ldu_memhog_root_page; @@ -89,7 +83,7 @@ kportal_memhog_free (struct libcfs_device_userstate *ldu) LASSERT(ldu->ldu_memhog_pages == 0); } -int +static int kportal_memhog_alloc(struct libcfs_device_userstate *ldu, int npages, gfp_t flags) { @@ -121,7 +115,7 @@ kportal_memhog_alloc(struct libcfs_device_userstate *ldu, int npages, while (ldu->ldu_memhog_pages < npages && count1 < PAGE_CACHE_SIZE/sizeof(struct page *)) { - if (cfs_signal_pending()) + if (signal_pending(current)) return -EINTR; *level1p = alloc_page(flags); @@ -136,7 +130,7 @@ kportal_memhog_alloc(struct libcfs_device_userstate *ldu, int npages, while (ldu->ldu_memhog_pages < npages && count2 < PAGE_CACHE_SIZE/sizeof(struct page *)) { - if (cfs_signal_pending()) + if (signal_pending(current)) return -EINTR; *level2p = alloc_page(flags); @@ -189,8 +183,8 @@ static int libcfs_psdev_release(unsigned long flags, void *args) RETURN(0); } -static struct rw_semaphore ioctl_list_sem; -static struct list_head ioctl_list; +static DECLARE_RWSEM(ioctl_list_sem); +static LIST_HEAD(ioctl_list); int libcfs_register_ioctl(struct libcfs_ioctl_handler *hand) { @@ -222,71 +216,65 @@ int libcfs_deregister_ioctl(struct libcfs_ioctl_handler *hand) } EXPORT_SYMBOL(libcfs_deregister_ioctl); -static int libcfs_ioctl_handle(struct cfs_psdev_file *pfile, unsigned long cmd, - void __user *arg, struct libcfs_ioctl_hdr *hdr) +static int libcfs_ioctl(struct cfs_psdev_file *pfile, + unsigned long cmd, void __user *uparam) { struct libcfs_ioctl_data *data = NULL; - int err; + struct libcfs_ioctl_hdr *hdr; + int err; ENTRY; - /* The libcfs_ioctl_data_adjust() function performs adjustment - * operations on the libcfs_ioctl_data structure to make - * it usable by the code. This doesn't need to be called - * for new data structures added. */ + /* 'cmd' and permissions get checked in our arch-specific caller */ + err = libcfs_ioctl_getdata(&hdr, uparam); + if (err != 0) { + CDEBUG_LIMIT(D_ERROR, + "libcfs ioctl: data header error %d\n", err); + RETURN(err); + } + if (hdr->ioc_version == LIBCFS_IOCTL_VERSION) { + /* The libcfs_ioctl_data_adjust() function performs adjustment + * operations on the libcfs_ioctl_data structure to make + * it usable by the code. This doesn't need to be called + * for new data structures added. */ data = container_of(hdr, struct libcfs_ioctl_data, ioc_hdr); err = libcfs_ioctl_data_adjust(data); - if (err != 0) { - RETURN(err); - } + if (err != 0) + GOTO(out, err); } + CDEBUG(D_IOCTL, "libcfs ioctl cmd %lu\n", cmd); switch (cmd) { case IOC_LIBCFS_CLEAR_DEBUG: libcfs_debug_clear_buffer(); - RETURN(0); + break; /* * case IOC_LIBCFS_PANIC: * Handled in arch/cfs_module.c */ case IOC_LIBCFS_MARK_DEBUG: - if (data->ioc_inlbuf1 == NULL || + if (data == NULL || + data->ioc_inlbuf1 == NULL || data->ioc_inlbuf1[data->ioc_inllen1 - 1] != '\0') - RETURN(-EINVAL); + GOTO(out, err = -EINVAL); + libcfs_debug_mark_buffer(data->ioc_inlbuf1); - RETURN(0); + break; + case IOC_LIBCFS_MEMHOG: - if (pfile->private_data == NULL) { - err = -EINVAL; - } else { + if (data == NULL) + GOTO(out, err = -EINVAL); + + if (pfile->private_data == NULL) + GOTO(out, err = -EINVAL); + + kportal_memhog_free(pfile->private_data); + err = kportal_memhog_alloc(pfile->private_data, + data->ioc_count, data->ioc_flags); + if (err != 0) kportal_memhog_free(pfile->private_data); - /* XXX The ioc_flags is not GFP flags now, need to - * be fixed */ - err = kportal_memhog_alloc(pfile->private_data, - data->ioc_count, - data->ioc_flags); - if (err != 0) - kportal_memhog_free(pfile->private_data); - } break; - case IOC_LIBCFS_PING_TEST: { - extern void (kping_client)(struct libcfs_ioctl_data *); - void (*ping)(struct libcfs_ioctl_data *); - - CDEBUG(D_IOCTL, "doing %d pings to nid %s (%s)\n", - data->ioc_count, libcfs_nid2str(data->ioc_nid), - libcfs_nid2str(data->ioc_nid)); - ping = symbol_get(kping_client); - if (!ping) { - CERROR("symbol_get failed\n"); - } else { - ping(data); - symbol_put(kping_client); - } - RETURN(0); - } - default: { struct libcfs_ioctl_handler *hand; @@ -294,60 +282,23 @@ static int libcfs_ioctl_handle(struct cfs_psdev_file *pfile, unsigned long cmd, down_read(&ioctl_list_sem); list_for_each_entry(hand, &ioctl_list, item) { err = hand->handle_ioctl(cmd, hdr); - if (err != -EINVAL) { - if (err == 0) - err = libcfs_ioctl_popdata(arg, - hdr, hdr->ioc_len); - break; + if (err == -EINVAL) + continue; + + if (err == 0) { + if (copy_to_user(uparam, hdr, hdr->ioc_len)) + err = -EFAULT; } + break; } up_read(&ioctl_list_sem); - break; - } - } - - RETURN(err); -} - -static int libcfs_ioctl(struct cfs_psdev_file *pfile, - unsigned long cmd, void __user *arg) -{ - struct libcfs_ioctl_hdr *hdr; - int err = 0; - __u32 buf_len; - ENTRY; - - err = libcfs_ioctl_getdata_len(arg, &buf_len); - if (err != 0) - RETURN(err); - - /* - * do a check here to restrict the size of the memory - * to allocate to guard against DoS attacks. - */ - if (buf_len > LNET_MAX_IOCTL_BUF_LEN) { - CERROR("LNET: user buffer exceeds kernel buffer\n"); - RETURN(-EINVAL); + break; } } - - LIBCFS_ALLOC_GFP(hdr, buf_len, GFP_IOFS); - if (hdr == NULL) - RETURN(-ENOMEM); - - /* 'cmd' and permissions get checked in our arch-specific caller */ - if (libcfs_ioctl_getdata(hdr, buf_len, arg)) { - CERROR("LNET ioctl: data error\n"); - GOTO(out, err = -EINVAL); - } - - err = libcfs_ioctl_handle(pfile, cmd, arg, hdr); - out: - LIBCFS_FREE(hdr, buf_len); + LIBCFS_FREE(hdr, hdr->ioc_len); RETURN(err); } - struct cfs_psdev_ops libcfs_psdev_ops = { libcfs_psdev_open, libcfs_psdev_release, @@ -356,33 +307,10 @@ struct cfs_psdev_ops libcfs_psdev_ops = { libcfs_ioctl }; -extern int insert_proc(void); -extern void remove_proc(void); -MODULE_AUTHOR("Peter J. Braam "); -MODULE_DESCRIPTION("Portals v3.1"); -MODULE_LICENSE("GPL"); - -extern struct miscdevice libcfs_dev; -extern struct rw_semaphore cfs_tracefile_sem; -extern struct mutex cfs_trace_thread_mutex; -extern struct cfs_wi_sched *cfs_sched_rehash; - -extern void libcfs_init_nidstrings(void); -extern int libcfs_arch_init(void); -extern void libcfs_arch_cleanup(void); - static int init_libcfs_module(void) { int rc; - libcfs_arch_init(); - libcfs_init_nidstrings(); - init_rwsem(&cfs_tracefile_sem); - mutex_init(&cfs_trace_thread_mutex); - init_rwsem(&ioctl_list_sem); - INIT_LIST_HEAD(&ioctl_list); - init_waitqueue_head(&cfs_race_waitq); - rc = libcfs_debug_init(5 * 1024 * 1024); if (rc < 0) { printk(KERN_ERR "LustreError: libcfs_debug_init: %d\n", rc); @@ -459,9 +387,7 @@ static void exit_libcfs_module(void) cfs_crypto_unregister(); cfs_wi_shutdown(); - rc = misc_deregister(&libcfs_dev); - if (rc) - CERROR("misc_deregister error %d\n", rc); + misc_deregister(&libcfs_dev); cfs_cpu_fini(); @@ -473,11 +399,12 @@ static void exit_libcfs_module(void) if (rc) printk(KERN_ERR "LustreError: libcfs_debug_cleanup: %d\n", rc); - - fini_rwsem(&ioctl_list_sem); - fini_rwsem(&cfs_tracefile_sem); - - libcfs_arch_cleanup(); } -cfs_module(libcfs, "1.0.0", init_libcfs_module, exit_libcfs_module); +MODULE_AUTHOR("OpenSFS, Inc. "); +MODULE_DESCRIPTION("Libcfs v3.1"); +MODULE_VERSION("1.0.0"); +MODULE_LICENSE("GPL"); + +module_init(init_libcfs_module); +module_exit(exit_libcfs_module);