X-Git-Url: https://git.whamcloud.com/?p=fs%2Flustre-release.git;a=blobdiff_plain;f=libcfs%2Flibcfs%2Fmodule.c;h=767bc071bc9e6a64f3dd79e561ed3b84651d08e4;hp=efd4213f16bffd157c47ba6fbeef506df2c4e986;hb=05d13ca333a3158a98f0c0e048a85564c6b9ed88;hpb=ed2430bd5a8b1b61ce9ae5c4a321598dee728199 diff --git a/libcfs/libcfs/module.c b/libcfs/libcfs/module.c index efd4213..767bc07 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/ @@ -39,10 +39,11 @@ #include #include #include +#include #include -#include "tracefile.h" +#include -void +static void kportal_memhog_free (struct libcfs_device_userstate *ldu) { struct page **level0p = &ldu->ldu_memhog_root_page; @@ -85,7 +86,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) { @@ -185,8 +186,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) { @@ -218,106 +219,87 @@ int libcfs_deregister_ioctl(struct libcfs_ioctl_handler *hand) } EXPORT_SYMBOL(libcfs_deregister_ioctl); -static int libcfs_ioctl_int(struct cfs_psdev_file *pfile,unsigned long cmd, - void *arg, struct libcfs_ioctl_data *data) +static int libcfs_ioctl(struct cfs_psdev_file *pfile, + unsigned long cmd, void __user *uparam) { - int err = -EINVAL; - ENTRY; - - switch (cmd) { - case IOC_LIBCFS_CLEAR_DEBUG: - libcfs_debug_clear_buffer(); - RETURN(0); - /* - * case IOC_LIBCFS_PANIC: - * Handled in arch/cfs_module.c - */ - case IOC_LIBCFS_MARK_DEBUG: - if (data->ioc_inlbuf1 == NULL || - data->ioc_inlbuf1[data->ioc_inllen1 - 1] != '\0') - RETURN(-EINVAL); - libcfs_debug_mark_buffer(data->ioc_inlbuf1); - RETURN(0); - case IOC_LIBCFS_MEMHOG: - if (pfile->private_data == NULL) { - err = -EINVAL; - } else { - 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); + struct libcfs_ioctl_data *data = NULL; + struct libcfs_ioctl_hdr *hdr; + int err; + ENTRY; + + /* '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); } - default: { - struct libcfs_ioctl_handler *hand; + 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) + GOTO(out, err); + } - err = -EINVAL; - down_read(&ioctl_list_sem); - list_for_each_entry(hand, &ioctl_list, item) { - err = hand->handle_ioctl(cmd, data); - if (err != -EINVAL) { - if (err == 0) - err = libcfs_ioctl_popdata(arg, - data, sizeof (*data)); - break; - } - } - up_read(&ioctl_list_sem); + CDEBUG(D_IOCTL, "libcfs ioctl cmd %lu\n", cmd); + switch (cmd) { + case IOC_LIBCFS_CLEAR_DEBUG: + libcfs_debug_clear_buffer(); + break; + /* + * case IOC_LIBCFS_PANIC: + * Handled in arch/cfs_module.c + */ + case IOC_LIBCFS_MARK_DEBUG: + if (data == NULL || + data->ioc_inlbuf1 == NULL || + data->ioc_inlbuf1[data->ioc_inllen1 - 1] != '\0') + GOTO(out, err = -EINVAL); + + libcfs_debug_mark_buffer(data->ioc_inlbuf1); break; - } - } - RETURN(err); -} + case IOC_LIBCFS_MEMHOG: + if (data == NULL) + GOTO(out, err = -EINVAL); -static int libcfs_ioctl(struct cfs_psdev_file *pfile, - unsigned long cmd, void *arg) -{ - char *buf; - struct libcfs_ioctl_data *data; - int err = 0; - ENTRY; + if (pfile->private_data == NULL) + GOTO(out, err = -EINVAL); - LIBCFS_ALLOC_GFP(buf, 1024, GFP_IOFS); - if (buf == NULL) - RETURN(-ENOMEM); + 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); + break; - /* 'cmd' and permissions get checked in our arch-specific caller */ - if (libcfs_ioctl_getdata(buf, buf + 800, (void *)arg)) { - CERROR("PORTALS ioctl: data error\n"); - GOTO(out, err = -EINVAL); - } - data = (struct libcfs_ioctl_data *)buf; + default: { + struct libcfs_ioctl_handler *hand; - err = libcfs_ioctl_int(pfile, cmd, arg, data); + err = -EINVAL; + down_read(&ioctl_list_sem); + list_for_each_entry(hand, &ioctl_list, item) { + err = hand->handle_ioctl(cmd, hdr); + if (err == -EINVAL) + continue; + if (err == 0) + err = libcfs_ioctl_popdata(hdr, uparam); + break; + } + up_read(&ioctl_list_sem); + break; } + } out: - LIBCFS_FREE(buf, 1024); - RETURN(err); + libcfs_ioctl_freedata(hdr); + RETURN(err); } - struct cfs_psdev_ops libcfs_psdev_ops = { libcfs_psdev_open, libcfs_psdev_release, @@ -326,32 +308,15 @@ 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) { @@ -444,9 +409,6 @@ static void exit_libcfs_module(void) printk(KERN_ERR "LustreError: libcfs_debug_cleanup: %d\n", rc); - fini_rwsem(&ioctl_list_sem); - fini_rwsem(&cfs_tracefile_sem); - libcfs_arch_cleanup(); }