linux/net/9p/mod.c
<<
>>
Prefs
   1/*
   2 *  net/9p/9p.c
   3 *
   4 *  9P entry point
   5 *
   6 *  Copyright (C) 2007 by Latchesar Ionkov <lucho@ionkov.net>
   7 *  Copyright (C) 2004 by Eric Van Hensbergen <ericvh@gmail.com>
   8 *  Copyright (C) 2002 by Ron Minnich <rminnich@lanl.gov>
   9 *
  10 *  This program is free software; you can redistribute it and/or modify
  11 *  it under the terms of the GNU General Public License version 2
  12 *  as published by the Free Software Foundation.
  13 *
  14 *  This program is distributed in the hope that it will be useful,
  15 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
  16 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  17 *  GNU General Public License for more details.
  18 *
  19 *  You should have received a copy of the GNU General Public License
  20 *  along with this program; if not, write to:
  21 *  Free Software Foundation
  22 *  51 Franklin Street, Fifth Floor
  23 *  Boston, MA  02111-1301  USA
  24 *
  25 */
  26
  27#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
  28
  29#include <linux/module.h>
  30#include <linux/errno.h>
  31#include <linux/sched.h>
  32#include <linux/moduleparam.h>
  33#include <net/9p/9p.h>
  34#include <linux/fs.h>
  35#include <linux/parser.h>
  36#include <net/9p/client.h>
  37#include <net/9p/transport.h>
  38#include <linux/list.h>
  39#include <linux/spinlock.h>
  40
  41#ifdef CONFIG_NET_9P_DEBUG
  42unsigned int p9_debug_level = 0;        /* feature-rific global debug level  */
  43EXPORT_SYMBOL(p9_debug_level);
  44module_param_named(debug, p9_debug_level, uint, 0);
  45MODULE_PARM_DESC(debug, "9P debugging level");
  46
  47void _p9_debug(enum p9_debug_flags level, const char *func,
  48                const char *fmt, ...)
  49{
  50        struct va_format vaf;
  51        va_list args;
  52
  53        if ((p9_debug_level & level) != level)
  54                return;
  55
  56        va_start(args, fmt);
  57
  58        vaf.fmt = fmt;
  59        vaf.va = &args;
  60
  61        if (level == P9_DEBUG_9P)
  62                pr_notice("(%8.8d) %pV", task_pid_nr(current), &vaf);
  63        else
  64                pr_notice("-- %s (%d): %pV", func, task_pid_nr(current), &vaf);
  65
  66        va_end(args);
  67}
  68EXPORT_SYMBOL(_p9_debug);
  69#endif
  70
  71/*
  72 * Dynamic Transport Registration Routines
  73 *
  74 */
  75
  76static DEFINE_SPINLOCK(v9fs_trans_lock);
  77static LIST_HEAD(v9fs_trans_list);
  78
  79/**
  80 * v9fs_register_trans - register a new transport with 9p
  81 * @m: structure describing the transport module and entry points
  82 *
  83 */
  84void v9fs_register_trans(struct p9_trans_module *m)
  85{
  86        spin_lock(&v9fs_trans_lock);
  87        list_add_tail(&m->list, &v9fs_trans_list);
  88        spin_unlock(&v9fs_trans_lock);
  89}
  90EXPORT_SYMBOL(v9fs_register_trans);
  91
  92/**
  93 * v9fs_unregister_trans - unregister a 9p transport
  94 * @m: the transport to remove
  95 *
  96 */
  97void v9fs_unregister_trans(struct p9_trans_module *m)
  98{
  99        spin_lock(&v9fs_trans_lock);
 100        list_del_init(&m->list);
 101        spin_unlock(&v9fs_trans_lock);
 102}
 103EXPORT_SYMBOL(v9fs_unregister_trans);
 104
 105/**
 106 * v9fs_get_trans_by_name - get transport with the matching name
 107 * @name: string identifying transport
 108 *
 109 */
 110struct p9_trans_module *v9fs_get_trans_by_name(char *s)
 111{
 112        struct p9_trans_module *t, *found = NULL;
 113
 114        spin_lock(&v9fs_trans_lock);
 115
 116        list_for_each_entry(t, &v9fs_trans_list, list)
 117                if (strcmp(t->name, s) == 0 &&
 118                    try_module_get(t->owner)) {
 119                        found = t;
 120                        break;
 121                }
 122
 123        spin_unlock(&v9fs_trans_lock);
 124        return found;
 125}
 126EXPORT_SYMBOL(v9fs_get_trans_by_name);
 127
 128/**
 129 * v9fs_get_default_trans - get the default transport
 130 *
 131 */
 132
 133struct p9_trans_module *v9fs_get_default_trans(void)
 134{
 135        struct p9_trans_module *t, *found = NULL;
 136
 137        spin_lock(&v9fs_trans_lock);
 138
 139        list_for_each_entry(t, &v9fs_trans_list, list)
 140                if (t->def && try_module_get(t->owner)) {
 141                        found = t;
 142                        break;
 143                }
 144
 145        if (!found)
 146                list_for_each_entry(t, &v9fs_trans_list, list)
 147                        if (try_module_get(t->owner)) {
 148                                found = t;
 149                                break;
 150                        }
 151
 152        spin_unlock(&v9fs_trans_lock);
 153        return found;
 154}
 155EXPORT_SYMBOL(v9fs_get_default_trans);
 156
 157/**
 158 * v9fs_put_trans - put trans
 159 * @m: transport to put
 160 *
 161 */
 162void v9fs_put_trans(struct p9_trans_module *m)
 163{
 164        if (m)
 165                module_put(m->owner);
 166}
 167
 168/**
 169 * init_p9 - Initialize module
 170 *
 171 */
 172static int __init init_p9(void)
 173{
 174        int ret = 0;
 175
 176        p9_error_init();
 177        pr_info("Installing 9P2000 support\n");
 178        p9_trans_fd_init();
 179
 180        return ret;
 181}
 182
 183/**
 184 * exit_p9 - shutdown module
 185 *
 186 */
 187
 188static void __exit exit_p9(void)
 189{
 190        pr_info("Unloading 9P2000 support\n");
 191
 192        p9_trans_fd_exit();
 193}
 194
 195module_init(init_p9)
 196module_exit(exit_p9)
 197
 198MODULE_AUTHOR("Latchesar Ionkov <lucho@ionkov.net>");
 199MODULE_AUTHOR("Eric Van Hensbergen <ericvh@gmail.com>");
 200MODULE_AUTHOR("Ron Minnich <rminnich@lanl.gov>");
 201MODULE_LICENSE("GPL");
 202