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/filecorefs/filecore_vfsops.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 /*      $NetBSD: filecore_vfsops.c,v 1.9.2.1 2004/05/29 09:05:15 tron Exp $     */
    2 
    3 /*-
    4  * Copyright (c) 1994 The Regents of the University of California.
    5  * All rights reserved.
    6  *
    7  * Redistribution and use in source and binary forms, with or without
    8  * modification, are permitted provided that the following conditions
    9  * are met:
   10  * 1. Redistributions of source code must retain the above copyright
   11  *    notice, this list of conditions and the following disclaimer.
   12  * 2. Redistributions in binary form must reproduce the above copyright
   13  *    notice, this list of conditions and the following disclaimer in the
   14  *    documentation and/or other materials provided with the distribution.
   15  * 3. Neither the name of the University nor the names of its contributors
   16  *    may be used to endorse or promote products derived from this software
   17  *    without specific prior written permission.
   18  *
   19  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
   20  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
   21  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
   22  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
   23  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
   24  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
   25  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
   26  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
   27  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
   28  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   29  * SUCH DAMAGE.
   30  *
   31  *      filecore_vfsops.c       1.1     1998/6/26
   32  */
   33 
   34 /*-
   35  * Copyright (c) 1998 Andrew McMurry
   36  *
   37  * Redistribution and use in source and binary forms, with or without
   38  * modification, are permitted provided that the following conditions
   39  * are met:
   40  * 1. Redistributions of source code must retain the above copyright
   41  *    notice, this list of conditions and the following disclaimer.
   42  * 2. Redistributions in binary form must reproduce the above copyright
   43  *    notice, this list of conditions and the following disclaimer in the
   44  *    documentation and/or other materials provided with the distribution.
   45  * 3. All advertising materials mentioning features or use of this software
   46  *    must display the following acknowledgement:
   47  *      This product includes software developed by the University of
   48  *      California, Berkeley and its contributors.
   49  * 4. Neither the name of the University nor the names of its contributors
   50  *    may be used to endorse or promote products derived from this software
   51  *    without specific prior written permission.
   52  *
   53  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
   54  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
   55  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
   56  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
   57  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
   58  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
   59  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
   60  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
   61  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
   62  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   63  * SUCH DAMAGE.
   64  *
   65  *      filecore_vfsops.c       1.1     1998/6/26
   66  */
   67 
   68 #include <sys/cdefs.h>
   69 __KERNEL_RCSID(0, "$NetBSD: filecore_vfsops.c,v 1.9.2.1 2004/05/29 09:05:15 tron Exp $");
   70 
   71 #if defined(_KERNEL_OPT)
   72 #include "opt_compat_netbsd.h"
   73 #endif
   74 
   75 #include <sys/param.h>
   76 #include <sys/systm.h>
   77 #include <sys/namei.h>
   78 #include <sys/proc.h>
   79 #include <sys/vnode.h>
   80 #include <miscfs/specfs/specdev.h>
   81 #include <sys/mount.h>
   82 #include <sys/buf.h>
   83 #include <sys/file.h>
   84 #include <sys/device.h>
   85 #include <sys/errno.h>
   86 #include <sys/malloc.h>
   87 #include <sys/pool.h>
   88 #include <sys/conf.h>
   89 #include <sys/sysctl.h>
   90 
   91 #include <fs/filecorefs/filecore.h>
   92 #include <fs/filecorefs/filecore_extern.h>
   93 #include <fs/filecorefs/filecore_node.h>
   94 #include <fs/filecorefs/filecore_mount.h>
   95 
   96 MALLOC_DEFINE(M_FILECOREMNT, "filecore mount", "Filecore FS mount structures");
   97 
   98 extern const struct vnodeopv_desc filecore_vnodeop_opv_desc;
   99 
  100 const struct vnodeopv_desc * const filecore_vnodeopv_descs[] = {
  101         &filecore_vnodeop_opv_desc,
  102         NULL,
  103 };
  104 
  105 struct vfsops filecore_vfsops = {
  106         MOUNT_FILECORE,
  107         filecore_mount,
  108         filecore_start,
  109         filecore_unmount,
  110         filecore_root,
  111         filecore_quotactl,
  112         filecore_statfs,
  113         filecore_sync,
  114         filecore_vget,
  115         filecore_fhtovp,
  116         filecore_vptofh,
  117         filecore_init,
  118         filecore_reinit,
  119         filecore_done,
  120         NULL,
  121         NULL,                           /* filecore_mountroot */
  122         filecore_checkexp,
  123         filecore_vnodeopv_descs,
  124 };
  125 
  126 struct genfs_ops filecore_genfsops = {
  127         genfs_size,
  128 };
  129 
  130 /*
  131  * Called by vfs_mountroot when iso is going to be mounted as root.
  132  *
  133  * Name is updated by mount(8) after booting.
  134  */
  135 
  136 static int filecore_mountfs __P((struct vnode *devvp, struct mount *mp,
  137                 struct proc *p, struct filecore_args *argp));
  138 
  139 #if 0
  140 int
  141 filecore_mountroot()
  142 {
  143         struct mount *mp;
  144         extern struct vnode *rootvp;
  145         struct proc *p = curproc;       /* XXX */
  146         int error;
  147         struct filecore_args args;
  148 
  149         if (root_device->dv_class != DV_DISK)
  150                 return (ENODEV);
  151         
  152         /*
  153          * Get vnodes for swapdev and rootdev.
  154          */
  155         if (bdevvp(rootdev, &rootvp))
  156                 panic("filecore_mountroot: can't setup rootvp");
  157 
  158         if ((error = vfs_rootmountalloc(MOUNT_FILECORE, "root_device", &mp)) != 0)
  159                 return (error);
  160 
  161         args.flags = FILECOREMNT_ROOT;
  162         if ((error = filecore_mountfs(rootvp, mp, p, &args)) != 0) {
  163                 mp->mnt_op->vfs_refcount--;
  164                 vfs_unbusy(mp);
  165                 free(mp, M_MOUNT);
  166                 return (error);
  167         }
  168         simple_lock(&mountlist_slock);
  169         CIRCLEQ_INSERT_TAIL(&mountlist, mp, mnt_list);
  170         simple_unlock(&mountlist_slock);
  171         (void)filecore_statfs(mp, &mp->mnt_stat, p);
  172         vfs_unbusy(mp);
  173         return (0);
  174 }
  175 #endif
  176 
  177 /*
  178  * VFS Operations.
  179  *
  180  * mount system call
  181  */
  182 int
  183 filecore_mount(mp, path, data, ndp, p)
  184         struct mount *mp;
  185         const char *path;
  186         void *data;
  187         struct nameidata *ndp;
  188         struct proc *p;
  189 {
  190         struct vnode *devvp;
  191         struct filecore_args args;
  192         int error;
  193         struct filecore_mnt *fcmp = NULL;
  194         
  195         if (mp->mnt_flag & MNT_GETARGS) {
  196                 fcmp = VFSTOFILECORE(mp);
  197                 if (fcmp == NULL)
  198                         return EIO;
  199                 args.flags = fcmp->fc_mntflags;
  200                 args.uid = fcmp->fc_uid;
  201                 args.gid = fcmp->fc_gid;
  202                 args.fspec = NULL;
  203                 vfs_showexport(mp, &args.export, &fcmp->fc_export);
  204                 return copyout(&args, data, sizeof(args));
  205         }
  206         error = copyin(data, (caddr_t)&args, sizeof (struct filecore_args));
  207         if (error)
  208                 return (error);
  209         
  210         if ((mp->mnt_flag & MNT_RDONLY) == 0)
  211                 return (EROFS);
  212         
  213         /*
  214          * If updating, check whether changing from read-only to
  215          * read/write; if there is no device name, that's all we do.
  216          */
  217         if (mp->mnt_flag & MNT_UPDATE) {
  218                 fcmp = VFSTOFILECORE(mp);
  219                 if (args.fspec == 0)
  220                         return (vfs_export(mp, &fcmp->fc_export, &args.export));
  221         }
  222         /*
  223          * Not an update, or updating the name: look up the name
  224          * and verify that it refers to a sensible block device.
  225          */
  226         NDINIT(ndp, LOOKUP, FOLLOW, UIO_USERSPACE, args.fspec, p);
  227         if ((error = namei(ndp)) != 0)
  228                 return (error);
  229         devvp = ndp->ni_vp;
  230 
  231         if (devvp->v_type != VBLK) {
  232                 vrele(devvp);
  233                 return ENOTBLK;
  234         }
  235         if (bdevsw_lookup(devvp->v_rdev) == NULL) {
  236                 vrele(devvp);
  237                 return ENXIO;
  238         }
  239         /*
  240          * If mount by non-root, then verify that user has necessary
  241          * permissions on the device.
  242          */
  243         if (p->p_ucred->cr_uid != 0) {
  244                 vn_lock(devvp, LK_EXCLUSIVE | LK_RETRY);
  245                 error = VOP_ACCESS(devvp, VREAD, p->p_ucred, p);
  246                 VOP_UNLOCK(devvp, 0);
  247                 if (error) {
  248                         vrele(devvp);
  249                         return (error);
  250                 }
  251         }
  252         if ((mp->mnt_flag & MNT_UPDATE) == 0)
  253                 error = filecore_mountfs(devvp, mp, p, &args);
  254         else {
  255                 if (devvp != fcmp->fc_devvp)
  256                         error = EINVAL; /* needs translation */
  257                 else
  258                         vrele(devvp);
  259         }
  260         if (error) {
  261                 vrele(devvp);
  262                 return error;
  263         }
  264         fcmp = VFSTOFILECORE(mp);
  265         return set_statfs_info(path, UIO_USERSPACE, args.fspec, UIO_USERSPACE,
  266             mp, p);
  267 }
  268 
  269 /*
  270  * Common code for mount and mountroot
  271  */
  272 static int
  273 filecore_mountfs(devvp, mp, p, argp)
  274         struct vnode *devvp;
  275         struct mount *mp;
  276         struct proc *p;
  277         struct filecore_args *argp;
  278 {
  279         struct filecore_mnt *fcmp = (struct filecore_mnt *)0;
  280         struct buf *bp = NULL;
  281         dev_t dev = devvp->v_rdev;
  282         int error = EINVAL;
  283         int ronly = (mp->mnt_flag & MNT_RDONLY) != 0;
  284         extern struct vnode *rootvp;
  285         struct filecore_disc_record *fcdr;
  286         unsigned map;
  287         unsigned log2secsize;
  288         
  289         if (!ronly)
  290                 return EROFS;
  291         
  292         /*
  293          * Disallow multiple mounts of the same device.
  294          * Disallow mounting of a device that is currently in use
  295          * (except for root, which might share swap device for miniroot).
  296          * Flush out any old buffers remaining from a previous use.
  297          */
  298         if ((error = vfs_mountedon(devvp)) != 0)
  299                 return error;
  300         if (vcount(devvp) > 1 && devvp != rootvp)
  301                 return EBUSY;
  302         if ((error = vinvalbuf(devvp, V_SAVE, p->p_ucred, p, 0, 0)) != 0)
  303                 return (error);
  304 
  305         error = VOP_OPEN(devvp, ronly ? FREAD : FREAD|FWRITE, FSCRED, p);
  306         if (error)
  307                 return error;
  308         
  309         /* Read the filecore boot block to check FS validity and to find the map */
  310         error = bread(devvp, FILECORE_BOOTBLOCK_BLKN,
  311                            FILECORE_BOOTBLOCK_SIZE, NOCRED, &bp);
  312 #ifdef FILECORE_DEBUG_BR
  313                 printf("bread(%p, %x, %d, CRED, %p)=%d\n", devvp,
  314                        FILECORE_BOOTBLOCK_BLKN, FILECORE_BOOTBLOCK_SIZE,
  315                        bp, error);
  316 #endif
  317         if (error != 0)
  318                 goto out;
  319         if (filecore_bbchecksum(bp->b_data) != 0) {
  320                 error = EINVAL;
  321                 goto out;
  322         }
  323         fcdr = (struct filecore_disc_record *)(bp->b_data+FILECORE_BB_DISCREC);
  324         map = ((((8 << fcdr->log2secsize) - fcdr->zone_spare)
  325             * (fcdr->nzones / 2) - 8 * FILECORE_DISCREC_SIZE)
  326             << fcdr->log2bpmb) >> fcdr->log2secsize;
  327         log2secsize = fcdr->log2secsize;
  328         bp->b_flags |= B_AGE;
  329 #ifdef FILECORE_DEBUG_BR
  330         printf("brelse(%p) vf1\n", bp);
  331 #endif
  332         brelse(bp);
  333         bp = NULL;
  334 
  335         /* Read the bootblock in the map */
  336         error = bread(devvp, map, 1 << log2secsize, NOCRED, &bp);
  337 #ifdef FILECORE_DEBUG_BR
  338                 printf("bread(%p, %x, %d, CRED, %p)=%d\n", devvp,
  339                        map, 1 << log2secsize, bp, error);
  340 #endif
  341         if (error != 0)
  342                 goto out;
  343         fcdr = (struct filecore_disc_record *)(bp->b_data + 4);
  344         fcmp = malloc(sizeof *fcmp, M_FILECOREMNT, M_WAITOK);
  345         memset((caddr_t)fcmp, 0, sizeof *fcmp);
  346         if (fcdr->log2bpmb > fcdr->log2secsize)
  347                 fcmp->log2bsize = fcdr->log2bpmb;
  348         else    fcmp->log2bsize = fcdr->log2secsize;
  349         fcmp->blksize = 1 << fcmp->log2bsize;
  350         memcpy((caddr_t)&fcmp->drec, (caddr_t)fcdr, sizeof(*fcdr));
  351         fcmp->map = map;
  352         fcmp->idspz = ((8 << fcdr->log2secsize) - fcdr->zone_spare)
  353             / (fcdr->idlen + 1);
  354         fcmp->mask = (1 << fcdr->idlen) - 1;
  355         if (fcdr->big_flag & 1) {
  356                 fcmp->nblks = ((((u_int64_t)fcdr->disc_size_2) << 32)
  357                     + fcdr->disc_size) / fcmp->blksize;
  358         } else {
  359                 fcmp->nblks=fcdr->disc_size / fcmp->blksize;
  360         }
  361 
  362         bp->b_flags |= B_AGE;
  363 #ifdef FILECORE_DEBUG_BR
  364         printf("brelse(%p) vf2\n", bp);
  365 #endif
  366         brelse(bp);
  367         bp = NULL;
  368 
  369         mp->mnt_data = fcmp;
  370         mp->mnt_stat.f_fsid.val[0] = (long)dev;
  371         mp->mnt_stat.f_fsid.val[1] = makefstype(MOUNT_FILECORE);
  372         mp->mnt_maxsymlinklen = 0;
  373         mp->mnt_flag |= MNT_LOCAL;
  374         mp->mnt_dev_bshift = fcdr->log2secsize;
  375         mp->mnt_fs_bshift = fcmp->log2bsize;
  376 
  377         fcmp->fc_mountp = mp;
  378         fcmp->fc_dev = dev;
  379         fcmp->fc_devvp = devvp;
  380         fcmp->fc_mntflags = argp->flags;
  381         if (argp->flags & FILECOREMNT_USEUID) {
  382                 fcmp->fc_uid = p->p_cred->p_ruid;
  383                 fcmp->fc_gid = p->p_cred->p_rgid;
  384         } else {
  385                 fcmp->fc_uid = argp->uid;
  386                 fcmp->fc_gid = argp->gid;
  387         }
  388         
  389         return 0;
  390 out:
  391         if (bp) {
  392 #ifdef FILECORE_DEBUG_BR
  393                 printf("brelse(%p) vf3\n", bp);
  394 #endif
  395                 brelse(bp);
  396         }
  397         vn_lock(devvp, LK_EXCLUSIVE | LK_RETRY);
  398         (void)VOP_CLOSE(devvp, ronly ? FREAD : FREAD|FWRITE, NOCRED, p);
  399         VOP_UNLOCK(devvp, 0);
  400         if (fcmp) {
  401                 free((caddr_t)fcmp, M_FILECOREMNT);
  402                 mp->mnt_data = NULL;
  403         }
  404         return error;
  405 }
  406 
  407 /*
  408  * Make a filesystem operational.
  409  * Nothing to do at the moment.
  410  */
  411 /* ARGSUSED */
  412 int
  413 filecore_start(mp, flags, p)
  414         struct mount *mp;
  415         int flags;
  416         struct proc *p;
  417 {
  418         return 0;
  419 }
  420 
  421 /*
  422  * unmount system call
  423  */
  424 int
  425 filecore_unmount(mp, mntflags, p)
  426         struct mount *mp;
  427         int mntflags;
  428         struct proc *p;
  429 {
  430         struct filecore_mnt *fcmp;
  431         int error, flags = 0;
  432         
  433         if (mntflags & MNT_FORCE)
  434                 flags |= FORCECLOSE;
  435 #if 0
  436         mntflushbuf(mp, 0);
  437         if (mntinvalbuf(mp))
  438                 return EBUSY;
  439 #endif
  440         if ((error = vflush(mp, NULLVP, flags)) != 0)
  441                 return (error);
  442 
  443         fcmp = VFSTOFILECORE(mp);
  444 
  445         if (fcmp->fc_devvp->v_type != VBAD)
  446                 fcmp->fc_devvp->v_specmountpoint = NULL;
  447         vn_lock(fcmp->fc_devvp, LK_EXCLUSIVE | LK_RETRY);
  448         error = VOP_CLOSE(fcmp->fc_devvp, FREAD, NOCRED, p);
  449         vput(fcmp->fc_devvp);
  450         free((caddr_t)fcmp, M_FILECOREMNT);
  451         mp->mnt_data = NULL;
  452         mp->mnt_flag &= ~MNT_LOCAL;
  453         return (error);
  454 }
  455 
  456 /*
  457  * Return root of a filesystem
  458  */
  459 int
  460 filecore_root(mp, vpp)
  461         struct mount *mp;
  462         struct vnode **vpp;
  463 {
  464         struct vnode *nvp;
  465         int error;
  466 
  467         if ((error = VFS_VGET(mp, FILECORE_ROOTINO, &nvp)) != 0)
  468                 return (error);
  469         *vpp = nvp;
  470         return (0);
  471 }
  472 
  473 /*
  474  * Do operations associated with quotas, not supported
  475  */
  476 /* ARGSUSED */
  477 int
  478 filecore_quotactl(mp, cmd, uid, arg, p)
  479         struct mount *mp;
  480         int cmd;
  481         uid_t uid;
  482         caddr_t arg;
  483         struct proc *p;
  484 {
  485 
  486         return (EOPNOTSUPP);
  487 }
  488 
  489 /*
  490  * Get file system statistics.
  491  */
  492 int
  493 filecore_statfs(mp, sbp, p)
  494         struct mount *mp;
  495         struct statfs *sbp;
  496         struct proc *p;
  497 {
  498         struct filecore_mnt *fcmp = VFSTOFILECORE(mp);
  499 
  500 #ifdef COMPAT_09
  501         sbp->f_type = 255;
  502 #else
  503         sbp->f_type = 0;
  504 #endif
  505         sbp->f_bsize = fcmp->blksize;
  506         sbp->f_iosize = sbp->f_bsize;   /* XXX */
  507         sbp->f_blocks = fcmp->nblks;
  508         sbp->f_bfree = 0; /* total free blocks */
  509         sbp->f_bavail = 0; /* blocks free for non superuser */
  510         sbp->f_files =  0; /* total files */
  511         sbp->f_ffree = 0; /* free file nodes */
  512         copy_statfs_info(sbp, mp);
  513         return 0;
  514 }
  515 
  516 /* ARGSUSED */
  517 int
  518 filecore_sync(mp, waitfor, cred, p)
  519         struct mount *mp;
  520         int waitfor;
  521         struct ucred *cred;
  522         struct proc *p;
  523 {
  524         return (0);
  525 }
  526 
  527 /*
  528  * File handle to vnode
  529  *
  530  * Have to be really careful about stale file handles:
  531  * - check that the inode number is in range
  532  * - call iget() to get the locked inode
  533  * - check for an unallocated inode (i_mode == 0)
  534  * - check that the generation number matches
  535  */
  536 
  537 struct ifid {
  538         ushort          ifid_len;
  539         ushort          ifid_pad;
  540         u_int32_t       ifid_ino;
  541 };
  542 
  543 /* ARGSUSED */
  544 int
  545 filecore_fhtovp(mp, fhp, vpp)
  546         struct mount *mp;
  547         struct fid *fhp;
  548         struct vnode **vpp;
  549 {
  550         struct ifid *ifhp = (struct ifid *)fhp;
  551         struct vnode *nvp;
  552         struct filecore_node *ip;
  553         int error;
  554         
  555         if ((error = VFS_VGET(mp, ifhp->ifid_ino, &nvp)) != 0) {
  556                 *vpp = NULLVP;
  557                 return (error);
  558         }
  559         ip = VTOI(nvp);
  560         if (filecore_staleinode(ip)) {
  561                 vput(nvp);
  562                 *vpp = NULLVP;
  563                 return (ESTALE);
  564         }
  565         *vpp = nvp;
  566         return (0);
  567 }
  568 
  569 /* ARGSUSED */
  570 int
  571 filecore_checkexp(mp, nam, exflagsp, credanonp)
  572         struct mount *mp;
  573         struct mbuf *nam;
  574         int *exflagsp;
  575         struct ucred **credanonp;
  576 {
  577         struct filecore_mnt *fcmp = VFSTOFILECORE(mp);
  578         struct netcred *np;
  579         
  580         /*
  581          * Get the export permission structure for this <mp, client> tuple.
  582          */
  583         np = vfs_export_lookup(mp, &fcmp->fc_export, nam);
  584         if (np == NULL)
  585                 return (EACCES);
  586 
  587         *exflagsp = np->netc_exflags;
  588         *credanonp = &np->netc_anon;
  589         return (0);
  590 }
  591 
  592 /* This looks complicated. Look at other vgets as well as the iso9660 one.
  593  *
  594  * The filecore inode number is made up of 1 byte directory entry index and
  595  * 3 bytes of the internal disc address of the directory. On a read-only
  596  * filesystem this is unique. For a read-write version we may not be able to
  597  * do vget, see msdosfs.
  598  */
  599 
  600 int
  601 filecore_vget(mp, ino, vpp)
  602         struct mount *mp;
  603         ino_t ino;
  604         struct vnode **vpp;
  605 {
  606         struct filecore_mnt *fcmp;
  607         struct filecore_node *ip;
  608         struct buf *bp;
  609         struct vnode *vp;
  610         dev_t dev;
  611         int error;
  612 
  613         fcmp = VFSTOFILECORE(mp);
  614         dev = fcmp->fc_dev;
  615         if ((*vpp = filecore_ihashget(dev, ino)) != NULLVP)
  616                 return (0);
  617 
  618         /* Allocate a new vnode/filecore_node. */
  619         if ((error = getnewvnode(VT_FILECORE, mp, filecore_vnodeop_p, &vp))
  620             != 0) {
  621                 *vpp = NULLVP;
  622                 return (error);
  623         }
  624         ip = pool_get(&filecore_node_pool, PR_WAITOK);
  625         memset(ip, 0, sizeof(struct filecore_node));
  626         vp->v_data = ip;
  627         ip->i_vnode = vp;
  628         ip->i_dev = dev;
  629         ip->i_number = ino;
  630         ip->i_block = -1;
  631         ip->i_parent = -2;
  632 
  633         /*
  634          * Put it onto its hash chain and lock it so that other requests for
  635          * this inode will block if they arrive while we are sleeping waiting
  636          * for old data structures to be purged or for the contents of the
  637          * disk portion of this inode to be read.
  638          */
  639         filecore_ihashins(ip);
  640 
  641         if (ino == FILECORE_ROOTINO) {
  642                 /* Here we need to construct a root directory inode */
  643                 memcpy((caddr_t)ip->i_dirent.name, (caddr_t)"root", 4);
  644                 ip->i_dirent.load = 0;
  645                 ip->i_dirent.exec = 0;
  646                 ip->i_dirent.len = FILECORE_DIR_SIZE;
  647                 ip->i_dirent.addr = fcmp->drec.root;
  648                 ip->i_dirent.attr = FILECORE_ATTR_DIR | FILECORE_ATTR_READ;
  649 
  650         } else {
  651                 /* Read in Data from Directory Entry */
  652                 if ((error = filecore_bread(fcmp, ino & FILECORE_INO_MASK,
  653                     FILECORE_DIR_SIZE, NOCRED, &bp)) != 0) {
  654                         vput(vp);
  655 #ifdef FILECORE_DEBUG_BR
  656                         printf("brelse(%p) vf4\n", bp);
  657 #endif
  658                         brelse(bp);
  659                         *vpp = NULL;
  660                         return (error);
  661                 }
  662                 
  663                 memcpy((caddr_t)&ip->i_dirent,
  664                     (caddr_t)fcdirentry(bp->b_data, ino >> FILECORE_INO_INDEX),
  665                     sizeof(struct filecore_direntry));
  666 #ifdef FILECORE_DEBUG_BR
  667                 printf("brelse(%p) vf5\n", bp);
  668 #endif
  669                 brelse(bp);
  670         }
  671 
  672         ip->i_mnt = fcmp;
  673         ip->i_devvp = fcmp->fc_devvp;
  674         ip->i_diroff = 0;
  675         VREF(ip->i_devvp);
  676 
  677         /*
  678          * Setup type
  679          */
  680         vp->v_type = VREG;
  681         if (ip->i_dirent.attr & FILECORE_ATTR_DIR)
  682                 vp->v_type = VDIR;
  683 
  684         /*
  685          * Initialize the associated vnode
  686          */
  687         switch (vp->v_type) {
  688         case VFIFO:
  689         case VCHR:
  690         case VBLK:
  691                 /*
  692                  * Devices not supported.
  693                  */
  694                 vput(vp);
  695                 return (EOPNOTSUPP);
  696         case VLNK:
  697         case VNON:
  698         case VSOCK:
  699         case VDIR:
  700         case VBAD:
  701         case VREG:
  702                 break;
  703         }
  704         
  705         if (ino == FILECORE_ROOTINO)
  706                 vp->v_flag |= VROOT;
  707 
  708         /*
  709          * XXX need generation number?
  710          */
  711 
  712         genfs_node_init(vp, &filecore_genfsops);
  713         vp->v_size = ip->i_size;
  714         *vpp = vp;
  715         return (0);
  716 }
  717 
  718 /*
  719  * Vnode pointer to File handle
  720  */
  721 /* ARGSUSED */
  722 int
  723 filecore_vptofh(vp, fhp)
  724         struct vnode *vp;
  725         struct fid *fhp;
  726 {
  727         struct filecore_node *ip = VTOI(vp);
  728         struct ifid *ifhp;
  729         
  730         ifhp = (struct ifid *)fhp;
  731         ifhp->ifid_len = sizeof(struct ifid);
  732         ifhp->ifid_ino = ip->i_number;
  733         return 0;
  734 }
  735 
  736 SYSCTL_SETUP(sysctl_vfs_filecore_setup, "sysctl vfs.filecore subtree setup")
  737 {
  738 
  739         sysctl_createv(clog, 0, NULL, NULL,
  740                        CTLFLAG_PERMANENT,
  741                        CTLTYPE_NODE, "vfs", NULL,
  742                        NULL, 0, NULL, 0,
  743                        CTL_VFS, CTL_EOL);
  744         sysctl_createv(clog, 0, NULL, NULL,
  745                        CTLFLAG_PERMANENT,
  746                        CTLTYPE_NODE, "filecore",
  747                        SYSCTL_DESCR("Acorn FILECORE file system"),
  748                        NULL, 0, NULL, 0,
  749                        CTL_VFS, 19, CTL_EOL);
  750         /*
  751          * XXX the "19" above could be dynamic, thereby eliminating
  752          * one more instance of the "number to vfs" mapping problem,
  753          * but "19" is the order as taken from sys/mount.h
  754          */
  755 }

Cache object: 3e8eaed87d91d5658d4a7513ab9eae35


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