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/kern/vfs_init.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 /*
    2  * Copyright (c) 1989, 1993
    3  *      The Regents of the University of California.  All rights reserved.
    4  *
    5  * This code is derived from software contributed
    6  * to Berkeley by John Heidemann of the UCLA Ficus project.
    7  *
    8  * Source: * @(#)i405_init.c 2.10 92/04/27 UCLA Ficus project
    9  *
   10  * Redistribution and use in source and binary forms, with or without
   11  * modification, are permitted provided that the following conditions
   12  * are met:
   13  * 1. Redistributions of source code must retain the above copyright
   14  *    notice, this list of conditions and the following disclaimer.
   15  * 2. Redistributions in binary form must reproduce the above copyright
   16  *    notice, this list of conditions and the following disclaimer in the
   17  *    documentation and/or other materials provided with the distribution.
   18  * 3. All advertising materials mentioning features or use of this software
   19  *    must display the following acknowledgement:
   20  *      This product includes software developed by the University of
   21  *      California, Berkeley and its contributors.
   22  * 4. Neither the name of the University nor the names of its contributors
   23  *    may be used to endorse or promote products derived from this software
   24  *    without specific prior written permission.
   25  *
   26  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
   27  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
   28  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
   29  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
   30  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
   31  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
   32  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
   33  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
   34  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
   35  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   36  * SUCH DAMAGE.
   37  *
   38  *      @(#)vfs_init.c  8.3 (Berkeley) 1/4/94
   39  * $FreeBSD: src/sys/kern/vfs_init.c,v 1.20.4.1 1999/09/05 08:15:42 peter Exp $
   40  */
   41 
   42 
   43 #include <sys/param.h>
   44 #include <sys/systm.h>
   45 #include <sys/kernel.h>
   46 #include <sys/mount.h>
   47 #include <sys/time.h>
   48 #include <sys/vnode.h>
   49 #include <sys/stat.h>
   50 #include <sys/namei.h>
   51 #include <sys/ucred.h>
   52 #include <sys/buf.h>
   53 #include <sys/errno.h>
   54 #include <sys/malloc.h>
   55 #include <sys/proc.h>
   56 #include <vm/vm.h>
   57 #include <sys/sysctl.h>
   58 
   59 static void     vfs_op_init __P((void));
   60 
   61 static void vfsinit __P((void *));
   62 SYSINIT(vfs, SI_SUB_VFS, SI_ORDER_FIRST, vfsinit, NULL)
   63 
   64 /*
   65  * Sigh, such primitive tools are these...
   66  */
   67 #if 0
   68 #define DODEBUG(A) A
   69 #else
   70 #define DODEBUG(A)
   71 #endif
   72 
   73 struct vfsconf void_vfsconf;
   74 
   75 extern struct linker_set vfs_opv_descs_;
   76 #define vfs_opv_descs ((struct vnodeopv_desc **)vfs_opv_descs_.ls_items)
   77 
   78 extern struct linker_set vfs_set;
   79 struct vfsops *vfssw[MOUNT_MAXTYPE + 1];
   80 struct vfsconf *vfsconf[MOUNT_MAXTYPE + 1];
   81 
   82 extern struct vnodeop_desc *vfs_op_descs[];
   83                                 /* and the operations they perform */
   84 /*
   85  * This code doesn't work if the defn is **vnodop_defns with cc.
   86  * The problem is because of the compiler sometimes putting in an
   87  * extra level of indirection for arrays.  It's an interesting
   88  * "feature" of C.
   89  */
   90 static int vfs_opv_numops;
   91 
   92 /*
   93  * A miscellaneous routine.
   94  * A generic "default" routine that just returns an error.
   95  */
   96 int
   97 vn_default_error()
   98 {
   99 
  100         return (EOPNOTSUPP);
  101 }
  102 
  103 /*
  104  * vfs_init.c
  105  *
  106  * Allocate and fill in operations vectors.
  107  *
  108  * An undocumented feature of this approach to defining operations is that
  109  * there can be multiple entries in vfs_opv_descs for the same operations
  110  * vector. This allows third parties to extend the set of operations
  111  * supported by another layer in a binary compatibile way. For example,
  112  * assume that NFS needed to be modified to support Ficus. NFS has an entry
  113  * (probably nfs_vnopdeop_decls) declaring all the operations NFS supports by
  114  * default. Ficus could add another entry (ficus_nfs_vnodeop_decl_entensions)
  115  * listing those new operations Ficus adds to NFS, all without modifying the
  116  * NFS code. (Of couse, the OTW NFS protocol still needs to be munged, but
  117  * that is a(whole)nother story.) This is a feature.
  118  */
  119 void
  120 vfs_opv_init(struct vnodeopv_desc **them)
  121 {
  122         int i, j, k;
  123         vop_t ***opv_desc_vector_p;
  124         vop_t **opv_desc_vector;
  125         struct vnodeopv_entry_desc *opve_descp;
  126 
  127         /*
  128          * Allocate the dynamic vectors and fill them in.
  129          */
  130         for (i=0; them[i]; i++) {
  131                 opv_desc_vector_p = them[i]->opv_desc_vector_p;
  132                 /*
  133                  * Allocate and init the vector, if it needs it.
  134                  * Also handle backwards compatibility.
  135                  */
  136                 if (*opv_desc_vector_p == NULL) {
  137                         /* XXX - shouldn't be M_VNODE */
  138                         MALLOC(*opv_desc_vector_p, vop_t **,
  139                                vfs_opv_numops * sizeof(vop_t *), M_VNODE,
  140                                M_WAITOK);
  141                         bzero(*opv_desc_vector_p,
  142                               vfs_opv_numops * sizeof(vop_t *));
  143                         DODEBUG(printf("vector at %x allocated\n",
  144                             opv_desc_vector_p));
  145                 }
  146                 opv_desc_vector = *opv_desc_vector_p;
  147                 for (j=0; them[i]->opv_desc_ops[j].opve_op; j++) {
  148                         opve_descp = &(them[i]->opv_desc_ops[j]);
  149 
  150                         /*
  151                          * Sanity check:  is this operation listed
  152                          * in the list of operations?  We check this
  153                          * by seeing if its offest is zero.  Since
  154                          * the default routine should always be listed
  155                          * first, it should be the only one with a zero
  156                          * offset.  Any other operation with a zero
  157                          * offset is probably not listed in
  158                          * vfs_op_descs, and so is probably an error.
  159                          *
  160                          * A panic here means the layer programmer
  161                          * has committed the all-too common bug
  162                          * of adding a new operation to the layer's
  163                          * list of vnode operations but
  164                          * not adding the operation to the system-wide
  165                          * list of supported operations.
  166                          */
  167                         if (opve_descp->opve_op->vdesc_offset == 0 &&
  168                                     opve_descp->opve_op->vdesc_offset !=
  169                                         VOFFSET(vop_default)) {
  170                                 printf("operation %s not listed in %s.\n",
  171                                     opve_descp->opve_op->vdesc_name,
  172                                     "vfs_op_descs");
  173                                 panic ("vfs_opv_init: bad operation");
  174                         }
  175                         /*
  176                          * Fill in this entry.
  177                          */
  178                         opv_desc_vector[opve_descp->opve_op->vdesc_offset] =
  179                                         opve_descp->opve_impl;
  180                 }
  181         }
  182         /*
  183          * Finally, go back and replace unfilled routines
  184          * with their default.  (Sigh, an O(n^3) algorithm.  I
  185          * could make it better, but that'd be work, and n is small.)
  186          */
  187         for (i = 0; them[i]; i++) {
  188                 opv_desc_vector = *(them[i]->opv_desc_vector_p);
  189                 /*
  190                  * Force every operations vector to have a default routine.
  191                  */
  192                 if (opv_desc_vector[VOFFSET(vop_default)]==NULL) {
  193                         panic("vfs_opv_init: operation vector without default routine.");
  194                 }
  195                 for (k = 0; k<vfs_opv_numops; k++)
  196                         if (opv_desc_vector[k] == NULL)
  197                                 opv_desc_vector[k] =
  198                                         opv_desc_vector[VOFFSET(vop_default)];
  199         }
  200 }
  201 
  202 /*
  203  * Initialize known vnode operations vectors.
  204  */
  205 static void
  206 vfs_op_init()
  207 {
  208         int i;
  209 
  210         DODEBUG(printf("Vnode_interface_init.\n"));
  211         /*
  212          * Set all vnode vectors to a well known value.
  213          */
  214         for (i = 0; vfs_opv_descs[i]; i++)
  215                 *(vfs_opv_descs[i]->opv_desc_vector_p) = NULL;
  216         /*
  217          * Figure out how many ops there are by counting the table,
  218          * and assign each its offset.
  219          */
  220         for (vfs_opv_numops = 0, i = 0; vfs_op_descs[i]; i++) {
  221                 vfs_op_descs[i]->vdesc_offset = vfs_opv_numops;
  222                 vfs_opv_numops++;
  223         }
  224         DODEBUG(printf ("vfs_opv_numops=%d\n", vfs_opv_numops));
  225 }
  226 
  227 /*
  228  * Routines having to do with the management of the vnode table.
  229  */
  230 extern struct vnodeops dead_vnodeops;
  231 extern struct vnodeops spec_vnodeops;
  232 struct vattr va_null;
  233 
  234 /*
  235  * Initialize the vnode structures and initialize each file system type.
  236  */
  237 /* ARGSUSED*/
  238 static void
  239 vfsinit(dummy)
  240         void *dummy;
  241 {
  242         struct vfsops **vfsp;
  243         struct vfsconf **vfc;
  244         int i;
  245 
  246         /*
  247          * Initialize the VFS switch table
  248          */
  249         for(i = 0; i < MOUNT_MAXTYPE + 1; i++) {
  250                 vfsconf[i] = &void_vfsconf;
  251         }
  252 
  253         vfc = (struct vfsconf **)vfs_set.ls_items;
  254         while(*vfc) {
  255                 vfssw[(**vfc).vfc_index] = (**vfc).vfc_vfsops;
  256                 vfsconf[(**vfc).vfc_index] = *vfc;
  257                 vfc++;
  258         }
  259 
  260         /*
  261          * Initialize the vnode table
  262          */
  263         vntblinit();
  264         /*
  265          * Initialize the vnode name cache
  266          */
  267         nchinit();
  268         /*
  269          * Build vnode operation vectors.
  270          */
  271         vfs_op_init();
  272         vfs_opv_init(vfs_opv_descs);   /* finish the job */
  273         /*
  274          * Initialize each file system type.
  275          */
  276         vattr_null(&va_null);
  277         for (vfsp = &vfssw[0]; vfsp <= &vfssw[MOUNT_MAXTYPE]; vfsp++) {
  278                 if (*vfsp == NULL)
  279                         continue;
  280                 (*(*vfsp)->vfs_init)();
  281         }
  282 }
  283 
  284 /*
  285  * kernel related system variables.
  286  */
  287 
  288 static int
  289 sysctl_vfs_vfsconf SYSCTL_HANDLER_ARGS
  290 {
  291         int i, error;
  292 
  293         if (req->newptr)
  294                 return EINVAL;
  295         for(i = 0; i < MOUNT_MAXTYPE + 1; i++) {
  296                 error = SYSCTL_OUT(req, vfsconf[i], sizeof *vfsconf[i]);
  297                 if(error)
  298                         return error;
  299         }
  300         return (error);
  301 
  302 }
  303 
  304 SYSCTL_PROC(_vfs, VFS_VFSCONF, vfsconf, CTLTYPE_OPAQUE|CTLFLAG_RD,
  305         0, 0, sysctl_vfs_vfsconf, "S,vfsconf", "");
  306 
  307 /*
  308  * This goop is here to support a loadable NFS module... grumble...
  309  */
  310 void (*lease_check) __P((struct vnode *, struct proc *, struct ucred *, int))
  311      = 0;
  312 void (*lease_updatetime) __P((int))
  313      = 0;
  314 

Cache object: 9b0c93858e9244f4ce72386b2afbf2cc


[ 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.