The Design and Implementation of the FreeBSD Operating System, Second Edition
Now available: The Design and Implementation of the FreeBSD Operating System (Second Edition)


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/fs/intermezzo/sysctl.c

Version: -  FREEBSD  -  FREEBSD-13-STABLE  -  FREEBSD-13-0  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  l41  -  OPENBSD  -  linux-2.6  -  MK84  -  PLAN9  -  xnu-8792 
SearchContext: -  none  -  3  -  10 

    1 /* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*-
    2  * vim:expandtab:shiftwidth=8:tabstop=8:
    3  *
    4  *  Copyright (C) 1999 Peter J. Braam <braam@clusterfs.com>
    5  *
    6  *   This file is part of InterMezzo, http://www.inter-mezzo.org.
    7  *
    8  *   InterMezzo is free software; you can redistribute it and/or
    9  *   modify it under the terms of version 2 of the GNU General Public
   10  *   License as published by the Free Software Foundation.
   11  *
   12  *   InterMezzo is distributed in the hope that it will be useful,
   13  *   but WITHOUT ANY WARRANTY; without even the implied warranty of
   14  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   15  *   GNU General Public License for more details.
   16  *
   17  *   You should have received a copy of the GNU General Public License
   18  *   along with InterMezzo; if not, write to the Free Software
   19  *   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
   20  *
   21  *  Sysctrl entries for Intermezzo!
   22  */
   23 
   24 #define __NO_VERSION__
   25 #include <linux/config.h> /* for CONFIG_PROC_FS */
   26 #include <linux/module.h>
   27 #include <linux/sched.h>
   28 #include <linux/mm.h>
   29 #include <linux/sysctl.h>
   30 #include <linux/swapctl.h>
   31 #include <linux/proc_fs.h>
   32 #include <linux/slab.h>
   33 #include <linux/vmalloc.h>
   34 #include <linux/stat.h>
   35 #include <linux/ctype.h>
   36 #include <linux/init.h>
   37 #include <asm/bitops.h>
   38 #include <asm/segment.h>
   39 #include <asm/uaccess.h>
   40 #include <linux/utsname.h>
   41 #include <linux/blk.h>
   42 
   43 
   44 #include <linux/intermezzo_fs.h>
   45 #include <linux/intermezzo_psdev.h>
   46 
   47 /* /proc entries */
   48 
   49 #ifdef CONFIG_PROC_FS
   50 struct proc_dir_entry *proc_fs_intermezzo;
   51 int intermezzo_mount_get_info( char * buffer, char ** start, off_t offset,
   52                                int length)
   53 {
   54         int len=0;
   55 
   56         /* this works as long as we are below 1024 characters! */
   57         *start = buffer + offset;
   58         len -= offset;
   59 
   60         if ( len < 0 )
   61                 return -EINVAL;
   62 
   63         return len;
   64 }
   65 
   66 #endif
   67 
   68 
   69 /* SYSCTL below */
   70 
   71 static struct ctl_table_header *intermezzo_table_header = NULL;
   72 /* 0x100 to avoid any chance of collisions at any point in the tree with
   73  * non-directories
   74  */
   75 #define PSDEV_INTERMEZZO  (0x100)
   76 
   77 #define PSDEV_DEBUG        1      /* control debugging */
   78 #define PSDEV_TRACE        2      /* control enter/leave pattern */
   79 #define PSDEV_TIMEOUT      3      /* timeout on upcalls to become intrble */
   80 #define PSDEV_HARD         4      /* mount type "hard" or "soft" */
   81 #define PSDEV_NO_FILTER    5      /* controls presto_chk */
   82 #define PSDEV_NO_JOURNAL   6      /* controls presto_chk */
   83 #define PSDEV_NO_UPCALL    7      /* controls lento_upcall */
   84 #define PSDEV_ERRORVAL     8      /* controls presto_debug_fail_blkdev */
   85 #define PSDEV_EXCL_GID     9      /* which GID is ignored by presto */
   86 #define PSDEV_BYTES_TO_CLOSE 11   /* bytes to write before close */
   87 
   88 /* These are global presto control options */
   89 #define PRESTO_PRIMARY_CTLCNT 2
   90 static struct ctl_table presto_table[ PRESTO_PRIMARY_CTLCNT + MAX_CHANNEL + 1] =
   91 {
   92         {PSDEV_DEBUG, "debug", &presto_debug, sizeof(int), 0644, NULL, &proc_dointvec},
   93         {PSDEV_TRACE, "trace", &presto_print_entry, sizeof(int), 0644, NULL, &proc_dointvec},
   94 };
   95 
   96 /*
   97  * Intalling the sysctl entries: strategy
   98  * - have templates for each /proc/sys/intermezzo/ entry
   99  *   such an entry exists for each /dev/presto
  100  *    (proto_channel_entry)
  101  * - have a template for the contents of such directories
  102  *    (proto_psdev_table)
  103  * - have the master table (presto_table)
  104  *
  105  * When installing, malloc, memcpy and fix up the pointers to point to
  106  * the appropriate constants in izo_channels[your_minor]
  107  */
  108 
  109 static ctl_table proto_psdev_table[] = {
  110         {PSDEV_HARD, "hard", 0, sizeof(int), 0644, NULL, &proc_dointvec},
  111         {PSDEV_NO_FILTER, "no_filter", 0, sizeof(int), 0644, NULL, &proc_dointvec},
  112         {PSDEV_NO_JOURNAL, "no_journal", NULL, sizeof(int), 0644, NULL, &proc_dointvec},
  113         {PSDEV_NO_UPCALL, "no_upcall", NULL, sizeof(int), 0644, NULL, &proc_dointvec},
  114         {PSDEV_TIMEOUT, "timeout", NULL, sizeof(int), 0644, NULL, &proc_dointvec},
  115 #ifdef PRESTO_DEBUG
  116         {PSDEV_ERRORVAL, "errorval", NULL, sizeof(int), 0644, NULL, &proc_dointvec},
  117 #endif
  118         { 0 }
  119 };
  120 
  121 static ctl_table proto_channel_entry = {
  122         PSDEV_INTERMEZZO, 0,  NULL, 0, 0555, 0,
  123 };
  124 
  125 static ctl_table intermezzo_table[2] = {
  126         {PSDEV_INTERMEZZO, "intermezzo",    NULL, 0, 0555, presto_table},
  127         {0}
  128 };
  129 
  130 /* support for external setting and getting of opts. */
  131 /* particularly via ioctl. The Right way to do this is via sysctl,
  132  * but that will have to wait until intermezzo gets its own nice set of
  133  * sysctl IDs
  134  */
  135 /* we made these separate as setting may in future be more restricted
  136  * than getting
  137  */
  138 #ifdef RON_MINNICH
  139 int dosetopt(int minor, struct psdev_opt *opt)
  140 {
  141         int retval = 0;
  142         int newval = opt->optval;
  143 
  144         ENTRY;
  145 
  146         switch(opt->optname) {
  147 
  148         case PSDEV_TIMEOUT:
  149                 izo_channels[minor].uc_timeout = newval;
  150                 break;
  151 
  152         case PSDEV_HARD:
  153                 izo_channels[minor].uc_hard = newval;
  154                 break;
  155 
  156         case PSDEV_NO_FILTER:
  157                 izo_channels[minor].uc_no_filter = newval;
  158                 break;
  159 
  160         case PSDEV_NO_JOURNAL:
  161                 izo_channels[minor].uc_no_journal = newval;
  162                 break;
  163 
  164         case PSDEV_NO_UPCALL:
  165                 izo_channels[minor].uc_no_upcall = newval;
  166                 break;
  167 
  168 #ifdef PRESTO_DEBUG
  169         case PSDEV_ERRORVAL: {
  170                 /* If we have a positive arg, set a breakpoint for that
  171                  * value.  If we have a negative arg, make that device
  172                  * read-only.  FIXME  It would be much better to only
  173                  * allow setting the underlying device read-only for the
  174                  * current presto cache.
  175                  */
  176                 int errorval = izo_channels[minor].uc_errorval;
  177                 if (errorval < 0) {
  178                         if (newval == 0)
  179                                 set_device_ro(-errorval, 0);
  180                         else
  181                                 CERROR("device %s already read only\n",
  182                                        kdevname(-errorval));
  183                 } else {
  184                         if (newval < 0)
  185                                 set_device_ro(-newval, 1);
  186                         izo_channels[minor].uc_errorval = newval;
  187                         CDEBUG(D_PSDEV, "setting errorval to %d\n", newval);
  188                 }
  189 
  190                 break;
  191         }
  192 #endif
  193 
  194         case PSDEV_TRACE:
  195         case PSDEV_DEBUG:
  196         case PSDEV_BYTES_TO_CLOSE:
  197         default:
  198                 CDEBUG(D_PSDEV,
  199                        "ioctl: dosetopt: minor %d, bad optname 0x%x, \n",
  200                        minor, opt->optname);
  201 
  202                 retval = -EINVAL;
  203         }
  204 
  205         EXIT;
  206         return retval;
  207 }
  208 
  209 int dogetopt(int minor, struct psdev_opt *opt)
  210 {
  211         int retval = 0;
  212 
  213         ENTRY;
  214 
  215         switch(opt->optname) {
  216 
  217         case PSDEV_TIMEOUT:
  218                 opt->optval = izo_channels[minor].uc_timeout;
  219                 break;
  220 
  221         case PSDEV_HARD:
  222                 opt->optval = izo_channels[minor].uc_hard;
  223                 break;
  224 
  225         case PSDEV_NO_FILTER:
  226                 opt->optval = izo_channels[minor].uc_no_filter;
  227                 break;
  228 
  229         case PSDEV_NO_JOURNAL:
  230                 opt->optval = izo_channels[minor].uc_no_journal;
  231                 break;
  232 
  233         case PSDEV_NO_UPCALL:
  234                 opt->optval = izo_channels[minor].uc_no_upcall;
  235                 break;
  236 
  237 #ifdef PSDEV_DEBUG
  238         case PSDEV_ERRORVAL: {
  239                 int errorval = izo_channels[minor].uc_errorval;
  240                 if (errorval < 0 && is_read_only(-errorval))
  241                         CERROR("device %s has been set read-only\n",
  242                                kdevname(-errorval));
  243                 opt->optval = izo_channels[minor].uc_errorval;
  244                 break;
  245         }
  246 #endif
  247 
  248         case PSDEV_TRACE:
  249         case PSDEV_DEBUG:
  250         case PSDEV_BYTES_TO_CLOSE:
  251         default:
  252                 CDEBUG(D_PSDEV,
  253                        "ioctl: dogetopt: minor %d, bad optval 0x%x, \n",
  254                        minor, opt->optname);
  255 
  256                 retval = -EINVAL;
  257         }
  258 
  259         EXIT;
  260         return retval;
  261 }
  262 #endif
  263 
  264 
  265 /* allocate the tables for the presto devices. We need
  266  * sizeof(proto_channel_table)/sizeof(proto_channel_table[0])
  267  * entries for each dev
  268  */
  269 int /* __init */ init_intermezzo_sysctl(void)
  270 {
  271         int i;
  272         int total_dev = MAX_CHANNEL;
  273         int entries_per_dev = sizeof(proto_psdev_table) /
  274                 sizeof(proto_psdev_table[0]);
  275         int total_entries = entries_per_dev * total_dev;
  276         ctl_table *dev_ctl_table;
  277 
  278         PRESTO_ALLOC(dev_ctl_table, sizeof(ctl_table) * total_entries);
  279 
  280         if (! dev_ctl_table) {
  281                 CERROR("WARNING: presto couldn't allocate dev_ctl_table\n");
  282                 EXIT;
  283                 return -ENOMEM;
  284         }
  285 
  286         /* now fill in the entries ... we put the individual presto<x>
  287          * entries at the end of the table, and the per-presto stuff
  288          * starting at the front.  We assume that the compiler makes
  289          * this code more efficient, but really, who cares ... it
  290          * happens once per reboot.
  291          */
  292         for(i = 0; i < total_dev; i++) {
  293                 /* entry for this /proc/sys/intermezzo/intermezzo"i" */
  294                 ctl_table *psdev = &presto_table[i + PRESTO_PRIMARY_CTLCNT];
  295                 /* entries for the individual "files" in this "directory" */
  296                 ctl_table *psdev_entries = &dev_ctl_table[i * entries_per_dev];
  297                 /* init the psdev and psdev_entries with the prototypes */
  298                 *psdev = proto_channel_entry;
  299                 memcpy(psdev_entries, proto_psdev_table,
  300                        sizeof(proto_psdev_table));
  301                 /* now specialize them ... */
  302                 /* the psdev has to point to psdev_entries, and fix the number */
  303                 psdev->ctl_name = psdev->ctl_name + i + 1; /* sorry */
  304 
  305                 PRESTO_ALLOC((void*)psdev->procname, PROCNAME_SIZE);
  306                 if (!psdev->procname) {
  307                         PRESTO_FREE(dev_ctl_table,
  308                                     sizeof(ctl_table) * total_entries);
  309                         return -ENOMEM;
  310                 }
  311                 sprintf((char *) psdev->procname, "intermezzo%d", i);
  312                 /* hook presto into */
  313                 psdev->child = psdev_entries;
  314 
  315                 /* now for each psdev entry ... */
  316                 psdev_entries[0].data = &(izo_channels[i].uc_hard);
  317                 psdev_entries[1].data = &(izo_channels[i].uc_no_filter);
  318                 psdev_entries[2].data = &(izo_channels[i].uc_no_journal);
  319                 psdev_entries[3].data = &(izo_channels[i].uc_no_upcall);
  320                 psdev_entries[4].data = &(izo_channels[i].uc_timeout);
  321 #ifdef PRESTO_DEBUG
  322                 psdev_entries[5].data = &(izo_channels[i].uc_errorval);
  323 #endif
  324         }
  325 
  326 
  327 #ifdef CONFIG_SYSCTL
  328         if ( !intermezzo_table_header )
  329                 intermezzo_table_header =
  330                         register_sysctl_table(intermezzo_table, 0);
  331 #endif
  332 #ifdef CONFIG_PROC_FS
  333         proc_fs_intermezzo = proc_mkdir("intermezzo", proc_root_fs);
  334         proc_fs_intermezzo->owner = THIS_MODULE;
  335         create_proc_info_entry("mounts", 0, proc_fs_intermezzo, 
  336                                intermezzo_mount_get_info);
  337 #endif
  338         return 0;
  339 }
  340 
  341 void cleanup_intermezzo_sysctl(void)
  342 {
  343         int total_dev = MAX_CHANNEL;
  344         int entries_per_dev = sizeof(proto_psdev_table) /
  345                 sizeof(proto_psdev_table[0]);
  346         int total_entries = entries_per_dev * total_dev;
  347         int i;
  348 
  349 #ifdef CONFIG_SYSCTL
  350         if ( intermezzo_table_header )
  351                 unregister_sysctl_table(intermezzo_table_header);
  352         intermezzo_table_header = NULL;
  353 #endif
  354         for(i = 0; i < total_dev; i++) {
  355                 /* entry for this /proc/sys/intermezzo/intermezzo"i" */
  356                 ctl_table *psdev = &presto_table[i + PRESTO_PRIMARY_CTLCNT];
  357                 PRESTO_FREE(psdev->procname, PROCNAME_SIZE);
  358         }
  359         /* presto_table[PRESTO_PRIMARY_CTLCNT].child points to the
  360          * dev_ctl_table previously allocated in init_intermezzo_psdev()
  361          */
  362         PRESTO_FREE(presto_table[PRESTO_PRIMARY_CTLCNT].child, sizeof(ctl_table) * total_entries);
  363 
  364 #if CONFIG_PROC_FS
  365         remove_proc_entry("mounts", proc_fs_intermezzo);
  366         remove_proc_entry("intermezzo", proc_root_fs);
  367 #endif
  368 }
  369 

Cache object: f95c4d5a168c8b76e3ad11665a8c1e1f


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]


This page is part of the FreeBSD/Linux Linux Kernel Cross-Reference, and was automatically generated using a modified version of the LXR engine.