root/ufs/ffs/ffs_vfsops.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. ffs_mountroot
  2. ffs_mount
  3. ffs_reload_vnode
  4. ffs_reload
  5. ffs_validate
  6. ffs_mountfs
  7. ffs_oldfscompat
  8. ffs1_compat_read
  9. ffs1_compat_write
  10. ffs_unmount
  11. ffs_flushfiles
  12. ffs_statfs
  13. ffs_sync_vnode
  14. ffs_sync
  15. ffs_vget
  16. ffs_fhtovp
  17. ffs_vptofh
  18. ffs_sbupdate
  19. ffs_init
  20. ffs_sysctl

    1 /*      $OpenBSD: ffs_vfsops.c,v 1.109 2007/08/04 03:33:31 art Exp $    */
    2 /*      $NetBSD: ffs_vfsops.c,v 1.19 1996/02/09 22:22:26 christos Exp $ */
    3 
    4 /*
    5  * Copyright (c) 1989, 1991, 1993, 1994
    6  *      The Regents of the University of California.  All rights reserved.
    7  *
    8  * Redistribution and use in source and binary forms, with or without
    9  * modification, are permitted provided that the following conditions
   10  * are met:
   11  * 1. Redistributions of source code must retain the above copyright
   12  *    notice, this list of conditions and the following disclaimer.
   13  * 2. Redistributions in binary form must reproduce the above copyright
   14  *    notice, this list of conditions and the following disclaimer in the
   15  *    documentation and/or other materials provided with the distribution.
   16  * 3. Neither the name of the University nor the names of its contributors
   17  *    may be used to endorse or promote products derived from this software
   18  *    without specific prior written permission.
   19  *
   20  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
   21  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
   22  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
   23  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
   24  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
   25  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
   26  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
   27  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
   28  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
   29  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   30  * SUCH DAMAGE.
   31  *
   32  *      @(#)ffs_vfsops.c        8.14 (Berkeley) 11/28/94
   33  */
   34 
   35 #include <sys/param.h>
   36 #include <sys/systm.h>
   37 #include <sys/namei.h>
   38 #include <sys/proc.h>
   39 #include <sys/kernel.h>
   40 #include <sys/vnode.h>
   41 #include <sys/socket.h>
   42 #include <sys/mount.h>
   43 #include <sys/buf.h>
   44 #include <sys/mbuf.h>
   45 #include <sys/file.h>
   46 #include <sys/disklabel.h>
   47 #include <sys/ioctl.h>
   48 #include <sys/errno.h>
   49 #include <sys/malloc.h>
   50 #include <sys/sysctl.h>
   51 #include <sys/pool.h>
   52 
   53 #include <dev/rndvar.h>
   54 
   55 #include <miscfs/specfs/specdev.h>
   56 
   57 #include <ufs/ufs/quota.h>
   58 #include <ufs/ufs/ufsmount.h>
   59 #include <ufs/ufs/inode.h>
   60 #include <ufs/ufs/dir.h>
   61 #include <ufs/ufs/ufs_extern.h>
   62 #include <ufs/ufs/dirhash.h>
   63 
   64 #include <ufs/ffs/fs.h>
   65 #include <ufs/ffs/ffs_extern.h>
   66 
   67 int ffs_sbupdate(struct ufsmount *, int);
   68 int ffs_reload_vnode(struct vnode *, void *);
   69 int ffs_sync_vnode(struct vnode *, void *);
   70 int ffs_validate(struct fs *);
   71 
   72 void ffs1_compat_read(struct fs *, struct ufsmount *, daddr64_t);
   73 void ffs1_compat_write(struct fs *, struct ufsmount *);
   74 
   75 const struct vfsops ffs_vfsops = {
   76         ffs_mount,
   77         ufs_start,
   78         ffs_unmount,
   79         ufs_root,
   80         ufs_quotactl,
   81         ffs_statfs,
   82         ffs_sync,
   83         ffs_vget,
   84         ffs_fhtovp,
   85         ffs_vptofh,
   86         ffs_init,
   87         ffs_sysctl,
   88         ufs_check_export
   89 };
   90 
   91 struct inode_vtbl ffs_vtbl = {
   92         ffs_truncate,
   93         ffs_update,
   94         ffs_inode_alloc,
   95         ffs_inode_free,
   96         ffs_balloc,
   97         ffs_bufatoff
   98 };
   99 
  100 
  101 /*
  102  * Called by main() when ufs is going to be mounted as root.
  103  */
  104 
  105 struct pool ffs_ino_pool;
  106 struct pool ffs_dinode1_pool;
  107 #ifdef FFS2
  108 struct pool ffs_dinode2_pool;
  109 #endif
  110 
  111 int
  112 ffs_mountroot(void)
  113 {
  114         struct fs *fs;
  115         struct mount *mp;
  116         struct proc *p = curproc;       /* XXX */
  117         struct ufsmount *ump;
  118         int error;
  119 
  120         /*
  121          * Get vnodes for swapdev and rootdev.
  122          */
  123         swapdev_vp = NULL;
  124         if ((error = bdevvp(swapdev, &swapdev_vp)) ||
  125             (error = bdevvp(rootdev, &rootvp))) {
  126                 printf("ffs_mountroot: can't setup bdevvp's\n");
  127                 if (swapdev_vp)
  128                         vrele(swapdev_vp);
  129                 return (error);
  130         }
  131 
  132         if ((error = vfs_rootmountalloc("ffs", "root_device", &mp)) != 0) {
  133                 vrele(swapdev_vp);
  134                 vrele(rootvp);
  135                 return (error);
  136         }
  137 
  138         if ((error = ffs_mountfs(rootvp, mp, p)) != 0) {
  139                 mp->mnt_vfc->vfc_refcount--;
  140                 vfs_unbusy(mp);
  141                 free(mp, M_MOUNT);
  142                 vrele(swapdev_vp);
  143                 vrele(rootvp);
  144                 return (error);
  145         }
  146 
  147         CIRCLEQ_INSERT_TAIL(&mountlist, mp, mnt_list);
  148         ump = VFSTOUFS(mp);
  149         fs = ump->um_fs;
  150         (void) copystr(mp->mnt_stat.f_mntonname, fs->fs_fsmnt, MNAMELEN - 1, 0);
  151         (void)ffs_statfs(mp, &mp->mnt_stat, p);
  152         vfs_unbusy(mp);
  153         inittodr(fs->fs_time);
  154 
  155         return (0);
  156 }
  157 
  158 /*
  159  * VFS Operations.
  160  *
  161  * mount system call
  162  */
  163 int
  164 ffs_mount(struct mount *mp, const char *path, void *data,
  165     struct nameidata *ndp, struct proc *p)
  166 {
  167         struct vnode *devvp;
  168         struct ufs_args args;
  169         struct ufsmount *ump = NULL;
  170         struct fs *fs;
  171         int error = 0, flags;
  172         int ronly;
  173         mode_t accessmode;
  174         size_t size;
  175 
  176         error = copyin(data, &args, sizeof (struct ufs_args));
  177         if (error)
  178                 return (error);
  179 
  180 #ifndef FFS_SOFTUPDATES
  181         if (mp->mnt_flag & MNT_SOFTDEP) {
  182                 printf("WARNING: soft updates isn't compiled in\n");
  183                 mp->mnt_flag &= ~MNT_SOFTDEP;
  184         }
  185 #endif
  186 
  187         /*
  188          * Soft updates is incompatible with "async",
  189          * so if we are doing softupdates stop the user
  190          * from setting the async flag.
  191          */
  192         if ((mp->mnt_flag & (MNT_SOFTDEP | MNT_ASYNC)) ==
  193             (MNT_SOFTDEP | MNT_ASYNC)) {
  194                 return (EINVAL);
  195         }
  196         /*
  197          * If updating, check whether changing from read-only to
  198          * read/write; if there is no device name, that's all we do.
  199          */
  200         if (mp->mnt_flag & MNT_UPDATE) {
  201                 ump = VFSTOUFS(mp);
  202                 fs = ump->um_fs;
  203                 devvp = ump->um_devvp;
  204                 error = 0;
  205                 ronly = fs->fs_ronly;
  206 
  207                 if (ronly == 0 && (mp->mnt_flag & MNT_RDONLY)) {
  208                         /* Flush any dirty data */
  209                         mp->mnt_flag &= ~MNT_RDONLY;
  210                         VFS_SYNC(mp, MNT_WAIT, p->p_ucred, p);
  211                         mp->mnt_flag |= MNT_RDONLY;
  212 
  213                         /*
  214                          * Get rid of files open for writing.
  215                          */
  216                         flags = WRITECLOSE;
  217                         if (mp->mnt_flag & MNT_FORCE)
  218                                 flags |= FORCECLOSE;
  219                         if (fs->fs_flags & FS_DOSOFTDEP) {
  220                                 error = softdep_flushfiles(mp, flags, p);
  221                                 mp->mnt_flag &= ~MNT_SOFTDEP;
  222                         } else
  223                                 error = ffs_flushfiles(mp, flags, p);
  224                         ronly = 1;
  225                 }
  226 
  227                 /*
  228                  * Flush soft dependencies if disabling it via an update
  229                  * mount. This may leave some items to be processed,
  230                  * so don't do this yet XXX.
  231                  */
  232                 if ((fs->fs_flags & FS_DOSOFTDEP) &&
  233                     !(mp->mnt_flag & MNT_SOFTDEP) &&
  234                     !(mp->mnt_flag & MNT_RDONLY) && fs->fs_ronly == 0) {
  235 #if 0
  236                         flags = WRITECLOSE;
  237                         if (mp->mnt_flag & MNT_FORCE)
  238                                 flags |= FORCECLOSE;
  239                         error = softdep_flushfiles(mp, flags, p);
  240 #elif FFS_SOFTUPDATES
  241                         mp->mnt_flag |= MNT_SOFTDEP;
  242 #endif
  243                 }
  244                 /*
  245                  * When upgrading to a softdep mount, we must first flush
  246                  * all vnodes. (not done yet -- see above)
  247                  */
  248                 if (!(fs->fs_flags & FS_DOSOFTDEP) &&
  249                     (mp->mnt_flag & MNT_SOFTDEP) && fs->fs_ronly == 0) {
  250 #if 0
  251                         flags = WRITECLOSE;
  252                         if (mp->mnt_flag & MNT_FORCE)
  253                                 flags |= FORCECLOSE;
  254                         error = ffs_flushfiles(mp, flags, p);
  255 #else
  256                         mp->mnt_flag &= ~MNT_SOFTDEP;
  257 #endif
  258                 }
  259 
  260                 if (!error && (mp->mnt_flag & MNT_RELOAD))
  261                         error = ffs_reload(mp, ndp->ni_cnd.cn_cred, p);
  262                 if (error)
  263                         goto error_1;
  264 
  265                 if (ronly && (mp->mnt_flag & MNT_WANTRDWR)) {
  266                         /*
  267                          * If upgrade to read-write by non-root, then verify
  268                          * that user has necessary permissions on the device.
  269                          */
  270                         if (suser(p, 0)) {
  271                                 vn_lock(devvp, LK_EXCLUSIVE | LK_RETRY, p);
  272                                 error = VOP_ACCESS(devvp, VREAD | VWRITE,
  273                                                    p->p_ucred, p);
  274                                 VOP_UNLOCK(devvp, 0, p);
  275                                 if (error)
  276                                         goto error_1;
  277                         }
  278 
  279                         if (fs->fs_clean == 0) {
  280 #if 0
  281                                 /*
  282                                  * It is safe mount unclean file system
  283                                  * if it was previously mounted with softdep
  284                                  * but we may loss space and must
  285                                  * sometimes run fsck manually.
  286                                  */
  287                                 if (fs->fs_flags & FS_DOSOFTDEP)
  288                                         printf(
  289 "WARNING: %s was not properly unmounted\n",
  290                                             fs->fs_fsmnt);
  291                                 else
  292 #endif
  293                                 if (mp->mnt_flag & MNT_FORCE) {
  294                                         printf(
  295 "WARNING: %s was not properly unmounted\n",
  296                                             fs->fs_fsmnt);
  297                                 } else {
  298                                         printf(
  299 "WARNING: R/W mount of %s denied.  Filesystem is not clean - run fsck\n",
  300                                             fs->fs_fsmnt);
  301                                         error = EROFS;
  302                                         goto error_1;
  303                                 }
  304                         }
  305 
  306                         if ((fs->fs_flags & FS_DOSOFTDEP)) {
  307                                 error = softdep_mount(devvp, mp, fs,
  308                                                       p->p_ucred);
  309                                 if (error)
  310                                         goto error_1;
  311                         }
  312                         fs->fs_contigdirs=(u_int8_t*)malloc((u_long)fs->fs_ncg,
  313                                                             M_UFSMNT, M_WAITOK);
  314                         bzero(fs->fs_contigdirs, fs->fs_ncg);
  315 
  316                         ronly = 0;
  317                 }
  318                 if (args.fspec == 0) {
  319                         /*
  320                          * Process export requests.
  321                          */
  322                         error = vfs_export(mp, &ump->um_export, 
  323                             &args.export_info);
  324                         if (error)
  325                                 goto error_1;
  326                         else
  327                                 goto success;
  328                 }
  329         }
  330         /*
  331          * Not an update, or updating the name: look up the name
  332          * and verify that it refers to a sensible block device.
  333          */
  334         NDINIT(ndp, LOOKUP, FOLLOW, UIO_USERSPACE, args.fspec, p);
  335         if ((error = namei(ndp)) != 0)
  336                 goto error_1;
  337 
  338         devvp = ndp->ni_vp;
  339 
  340         if (devvp->v_type != VBLK) {
  341                 error = ENOTBLK;
  342                 goto error_2;
  343         }
  344 
  345         if (major(devvp->v_rdev) >= nblkdev) {
  346                 error = ENXIO;
  347                 goto error_2;
  348         }
  349 
  350         /*
  351          * If mount by non-root, then verify that user has necessary
  352          * permissions on the device.
  353          */
  354         if (suser(p, 0)) {
  355                 accessmode = VREAD;
  356                 if ((mp->mnt_flag & MNT_RDONLY) == 0)
  357                         accessmode |= VWRITE;
  358                 vn_lock(devvp, LK_EXCLUSIVE | LK_RETRY, p);
  359                 error = VOP_ACCESS(devvp, accessmode, p->p_ucred, p);
  360                 VOP_UNLOCK(devvp, 0, p);
  361                 if (error)
  362                         goto error_2;
  363         }
  364 
  365         if (mp->mnt_flag & MNT_UPDATE) {
  366                 /*
  367                  * UPDATE
  368                  * If it's not the same vnode, or at least the same device
  369                  * then it's not correct.
  370                  */
  371 
  372                 if (devvp != ump->um_devvp) {
  373                         if (devvp->v_rdev == ump->um_devvp->v_rdev) {
  374                                 vrele(devvp);
  375                         } else {
  376                                 error = EINVAL; /* needs translation */
  377                         }
  378                 } else
  379                         vrele(devvp);
  380                 /*
  381                  * Update device name only on success
  382                  */
  383                 if (!error) {
  384                         /*
  385                          * Save "mounted from" info for mount point (NULL pad)
  386                          */
  387                         copyinstr(args.fspec,
  388                                   mp->mnt_stat.f_mntfromname,
  389                                   MNAMELEN - 1,
  390                                   &size);
  391                         bzero(mp->mnt_stat.f_mntfromname + size,
  392                               MNAMELEN - size);
  393                 }
  394         } else {
  395                 /*
  396                  * Since this is a new mount, we want the names for
  397                  * the device and the mount point copied in.  If an
  398                  * error occurs,  the mountpoint is discarded by the
  399                  * upper level code.
  400                  */
  401                 /* Save "last mounted on" info for mount point (NULL pad)*/
  402                 copyinstr(path,                         /* mount point*/
  403                           mp->mnt_stat.f_mntonname,     /* save area*/
  404                           MNAMELEN - 1,                 /* max size*/
  405                           &size);                       /* real size*/
  406                 bzero(mp->mnt_stat.f_mntonname + size, MNAMELEN - size);
  407 
  408                 /* Save "mounted from" info for mount point (NULL pad)*/
  409                 copyinstr(args.fspec,                   /* device name*/
  410                           mp->mnt_stat.f_mntfromname,   /* save area*/
  411                           MNAMELEN - 1,                 /* max size*/
  412                           &size);                       /* real size*/
  413                 bzero(mp->mnt_stat.f_mntfromname + size, MNAMELEN - size);
  414 
  415                 error = ffs_mountfs(devvp, mp, p);
  416         }
  417 
  418         if (error)
  419                 goto error_2;
  420 
  421         /*
  422          * Initialize FS stat information in mount struct; uses both
  423          * mp->mnt_stat.f_mntonname and mp->mnt_stat.f_mntfromname
  424          *
  425          * This code is common to root and non-root mounts
  426          */
  427         bcopy(&args, &mp->mnt_stat.mount_info.ufs_args, sizeof(args));
  428         (void)VFS_STATFS(mp, &mp->mnt_stat, p);
  429 
  430 success:
  431         if (path && (mp->mnt_flag & MNT_UPDATE)) {
  432                 /* Update clean flag after changing read-onlyness. */
  433                 fs = ump->um_fs;
  434                 if (ronly != fs->fs_ronly) {
  435                         fs->fs_ronly = ronly;
  436                         fs->fs_clean = ronly &&
  437                             (fs->fs_flags & FS_UNCLEAN) == 0 ? 1 : 0;
  438                         if (ronly)
  439                                 free(fs->fs_contigdirs, M_UFSMNT);
  440                 }
  441                 if (!ronly) {
  442                         if (mp->mnt_flag & MNT_SOFTDEP)
  443                                 fs->fs_flags |= FS_DOSOFTDEP;
  444                         else
  445                                 fs->fs_flags &= ~FS_DOSOFTDEP;
  446                 }
  447                 ffs_sbupdate(ump, MNT_WAIT);
  448         }
  449         return (0);
  450 
  451 error_2:        /* error with devvp held */
  452         vrele (devvp);
  453 error_1:        /* no state to back out */
  454         return (error);
  455 }
  456 
  457 struct ffs_reload_args {
  458         struct fs *fs;
  459         struct proc *p;
  460         struct ucred *cred;
  461         struct vnode *devvp;
  462 };
  463 
  464 int
  465 ffs_reload_vnode(struct vnode *vp, void *args) 
  466 {
  467         struct ffs_reload_args *fra = args;
  468         struct inode *ip;
  469         struct buf *bp;
  470         int error;
  471 
  472         /*
  473          * Step 4: invalidate all inactive vnodes.
  474          */
  475         if (vp->v_usecount == 0) {
  476                 vgonel(vp, fra->p);
  477                 return (0);
  478         }
  479 
  480         /*
  481          * Step 5: invalidate all cached file data.
  482          */
  483         if (vget(vp, LK_EXCLUSIVE, fra->p))
  484                 return (0);
  485 
  486         if (vinvalbuf(vp, 0, fra->cred, fra->p, 0, 0))
  487                 panic("ffs_reload: dirty2");
  488 
  489         /*
  490          * Step 6: re-read inode data for all active vnodes.
  491          */
  492         ip = VTOI(vp);
  493 
  494         error = bread(fra->devvp, 
  495             fsbtodb(fra->fs, ino_to_fsba(fra->fs, ip->i_number)),
  496             (int)fra->fs->fs_bsize, NOCRED, &bp);
  497         if (error) {
  498                 brelse(bp);
  499                 vput(vp);
  500                 return (error);
  501         }
  502 
  503         *ip->i_din1 = *((struct ufs1_dinode *)bp->b_data +
  504             ino_to_fsbo(fra->fs, ip->i_number));
  505         ip->i_effnlink = DIP(ip, nlink);
  506         brelse(bp);
  507         vput(vp);
  508         return (0);
  509 }
  510 
  511 /*
  512  * Reload all incore data for a filesystem (used after running fsck on
  513  * the root filesystem and finding things to fix). The filesystem must
  514  * be mounted read-only.
  515  *
  516  * Things to do to update the mount:
  517  *      1) invalidate all cached meta-data.
  518  *      2) re-read superblock from disk.
  519  *      3) re-read summary information from disk.
  520  *      4) invalidate all inactive vnodes.
  521  *      5) invalidate all cached file data.
  522  *      6) re-read inode data for all active vnodes.
  523  */
  524 int
  525 ffs_reload(struct mount *mountp, struct ucred *cred, struct proc *p)
  526 {
  527         struct vnode *devvp;
  528         caddr_t space;
  529         struct fs *fs, *newfs;
  530         struct partinfo dpart;
  531         int i, blks, size, error;
  532         int32_t *lp;
  533         struct buf *bp = NULL;
  534         struct ffs_reload_args fra;
  535 
  536         if ((mountp->mnt_flag & MNT_RDONLY) == 0)
  537                 return (EINVAL);
  538         /*
  539          * Step 1: invalidate all cached meta-data.
  540          */
  541         devvp = VFSTOUFS(mountp)->um_devvp;
  542         vn_lock(devvp, LK_EXCLUSIVE | LK_RETRY, p);
  543         error = vinvalbuf(devvp, 0, cred, p, 0, 0);
  544         VOP_UNLOCK(devvp, 0, p);
  545         if (error)
  546                 panic("ffs_reload: dirty1");
  547 
  548         /*
  549          * Step 2: re-read superblock from disk.
  550          */
  551         if (VOP_IOCTL(devvp, DIOCGPART, (caddr_t)&dpart, FREAD, NOCRED, p) != 0)
  552                 size = DEV_BSIZE;
  553         else
  554                 size = dpart.disklab->d_secsize;
  555 
  556         fs = VFSTOUFS(mountp)->um_fs;
  557 
  558         error = bread(devvp, (daddr_t)(fs->fs_sblockloc / size), SBSIZE,
  559             NOCRED, &bp);
  560         if (error) {
  561                 brelse(bp);
  562                 return (error);
  563         }
  564 
  565         newfs = (struct fs *)bp->b_data;
  566         if (ffs_validate(newfs) == 0) {
  567                 brelse(bp);
  568                 return (EINVAL);
  569         }
  570 
  571         /*
  572          * Copy pointer fields back into superblock before copying in   XXX
  573          * new superblock. These should really be in the ufsmount.      XXX
  574          * Note that important parameters (eg fs_ncg) are unchanged.
  575          */
  576         newfs->fs_csp = fs->fs_csp;
  577         newfs->fs_maxcluster = fs->fs_maxcluster;
  578         newfs->fs_ronly = fs->fs_ronly;
  579         bcopy(newfs, fs, (u_int)fs->fs_sbsize);
  580         if (fs->fs_sbsize < SBSIZE)
  581                 bp->b_flags |= B_INVAL;
  582         brelse(bp);
  583         mountp->mnt_maxsymlinklen = fs->fs_maxsymlinklen;
  584         ffs1_compat_read(fs, VFSTOUFS(mountp), fs->fs_sblockloc);
  585         ffs_oldfscompat(fs);
  586         (void)ffs_statfs(mountp, &mountp->mnt_stat, p);
  587         /*
  588          * Step 3: re-read summary information from disk.
  589          */
  590         blks = howmany(fs->fs_cssize, fs->fs_fsize);
  591         space = (caddr_t)fs->fs_csp;
  592         for (i = 0; i < blks; i += fs->fs_frag) {
  593                 size = fs->fs_bsize;
  594                 if (i + fs->fs_frag > blks)
  595                         size = (blks - i) * fs->fs_fsize;
  596                 error = bread(devvp, fsbtodb(fs, fs->fs_csaddr + i), size,
  597                               NOCRED, &bp);
  598                 if (error) {
  599                         brelse(bp);
  600                         return (error);
  601                 }
  602                 bcopy(bp->b_data, space, (u_int)size);
  603                 space += size;
  604                 brelse(bp);
  605         }
  606         if ((fs->fs_flags & FS_DOSOFTDEP))
  607                 (void) softdep_mount(devvp, mountp, fs, cred);
  608         /*
  609          * We no longer know anything about clusters per cylinder group.
  610          */
  611         if (fs->fs_contigsumsize > 0) {
  612                 lp = fs->fs_maxcluster;
  613                 for (i = 0; i < fs->fs_ncg; i++)
  614                         *lp++ = fs->fs_contigsumsize;
  615         }
  616 
  617         fra.p = p;
  618         fra.cred = cred;
  619         fra.fs = fs;
  620         fra.devvp = devvp;
  621 
  622         error = vfs_mount_foreach_vnode(mountp, ffs_reload_vnode, &fra);
  623 
  624         return (error);
  625 }
  626 
  627 /*
  628  * Checks if a super block is sane enough to be mounted.
  629  */
  630 int
  631 ffs_validate(struct fs *fsp)
  632 {
  633 #ifdef FFS2
  634         if (fsp->fs_magic != FS_UFS2_MAGIC && fsp->fs_magic != FS_UFS1_MAGIC)
  635                 return (0); /* Invalid magic */
  636 #else
  637         if (fsp->fs_magic != FS_UFS1_MAGIC)
  638                 return (0); /* Invalid magic */
  639 #endif /* FFS2 */
  640 
  641         if ((u_int)fsp->fs_bsize > MAXBSIZE)
  642                 return (0); /* Invalid block size */
  643 
  644         if ((u_int)fsp->fs_bsize < sizeof(struct fs))
  645                 return (0); /* Invalid block size */
  646 
  647         if ((u_int)fsp->fs_sbsize > SBSIZE)
  648                 return (0); /* Invalid super block size */
  649 
  650         if ((u_int)fsp->fs_frag > MAXFRAG || fragtbl[fsp->fs_frag] == NULL)
  651                 return (0); /* Invalid number of fragments */
  652 
  653         return (1); /* Super block is okay */
  654 }
  655 
  656 /*
  657  * Possible locations for the super-block.
  658  */
  659 const int sbtry[] = SBLOCKSEARCH;
  660 
  661 /*
  662  * Common code for mount and mountroot
  663  */
  664 int
  665 ffs_mountfs(struct vnode *devvp, struct mount *mp, struct proc *p)
  666 {
  667         struct ufsmount *ump;
  668         struct buf *bp;
  669         struct fs *fs;
  670         dev_t dev;
  671         struct partinfo dpart;
  672         caddr_t space;
  673         daddr64_t sbloc;
  674         int error, i, blks, size, ronly;
  675         int32_t *lp;
  676         size_t strsize;
  677         struct ucred *cred;
  678         u_int64_t maxfilesize;                                  /* XXX */
  679 
  680         dev = devvp->v_rdev;
  681         cred = p ? p->p_ucred : NOCRED;
  682         /*
  683          * Disallow multiple mounts of the same device.
  684          * Disallow mounting of a device that is currently in use
  685          * (except for root, which might share swap device for miniroot).
  686          * Flush out any old buffers remaining from a previous use.
  687          */
  688         if ((error = vfs_mountedon(devvp)) != 0)
  689                 return (error);
  690         if (vcount(devvp) > 1 && devvp != rootvp)
  691                 return (EBUSY);
  692         vn_lock(devvp, LK_EXCLUSIVE | LK_RETRY, p);
  693         error = vinvalbuf(devvp, V_SAVE, cred, p, 0, 0);
  694         VOP_UNLOCK(devvp, 0, p);
  695         if (error)
  696                 return (error);
  697 
  698         ronly = (mp->mnt_flag & MNT_RDONLY) != 0;
  699         error = VOP_OPEN(devvp, ronly ? FREAD : FREAD|FWRITE, FSCRED, p);
  700         if (error)
  701                 return (error);
  702         if (VOP_IOCTL(devvp, DIOCGPART, (caddr_t)&dpart, FREAD, cred, p) != 0)
  703                 size = DEV_BSIZE;
  704         else
  705                 size = dpart.disklab->d_secsize;
  706 
  707         bp = NULL;
  708         ump = NULL;
  709 
  710         /*
  711          * Try reading the super-block in each of its possible locations.
  712          */
  713         for (i = 0; sbtry[i] != -1; i++) {
  714                 if (bp != NULL) {
  715                         bp->b_flags |= B_NOCACHE;
  716                         brelse(bp);
  717                         bp = NULL;
  718                 }
  719 
  720                 error = bread(devvp, sbtry[i] / size, SBSIZE, cred, &bp);
  721                 if (error)
  722                         goto out;
  723 
  724                 fs = (struct fs *) bp->b_data;
  725                 sbloc = sbtry[i];
  726 
  727 #if 0
  728                 if (fs->fs_magic == FS_UFS2_MAGIC) {
  729                         printf("ffs_mountfs(): Sorry, no UFS2 support (yet)\n");
  730                         error = EFTYPE;
  731                         goto out;
  732                 }
  733 #endif
  734 
  735                 /*
  736                  * Do not look for an FFS1 file system at SBLOCK_UFS2. Doing so
  737                  * will find the wrong super-block for file systems with 64k
  738                  * block size.
  739                  */
  740                 if (fs->fs_magic == FS_UFS1_MAGIC && sbloc == SBLOCK_UFS2)
  741                         continue;
  742 
  743                 if (ffs_validate(fs))
  744                         break; /* Super block validated */
  745         }
  746 
  747         if (sbtry[i] == -1) {
  748                 error = EINVAL;
  749                 goto out;
  750         }
  751 
  752         fs->fs_fmod = 0;
  753         fs->fs_flags &= ~FS_UNCLEAN;
  754         if (fs->fs_clean == 0) {
  755 #if 0
  756                 /*
  757                  * It is safe mount unclean file system
  758                  * if it was previously mounted with softdep
  759                  * but we may loss space and must
  760                  * sometimes run fsck manually.
  761                  */
  762                 if (fs->fs_flags & FS_DOSOFTDEP)
  763                         printf(
  764 "WARNING: %s was not properly unmounted\n",
  765                             fs->fs_fsmnt);
  766                 else
  767 #endif
  768                 if (ronly || (mp->mnt_flag & MNT_FORCE)) {
  769                         printf(
  770 "WARNING: %s was not properly unmounted\n",
  771                             fs->fs_fsmnt);
  772                 } else {
  773                         printf(
  774 "WARNING: R/W mount of %s denied.  Filesystem is not clean - run fsck\n",
  775                             fs->fs_fsmnt);
  776                         error = EROFS;
  777                         goto out;
  778                 }
  779         }
  780 
  781         if (fs->fs_postblformat == FS_42POSTBLFMT && !ronly) {
  782 #ifndef SMALL_KERNEL
  783                 printf("ffs_mountfs(): obsolete rotational table format, "
  784                     "please use fsck_ffs(8) -c 1\n");
  785 #endif
  786                 error = EFTYPE;
  787                 goto out;
  788         }
  789 
  790         ump = malloc(sizeof *ump, M_UFSMNT, M_WAITOK);
  791         bzero(ump, sizeof *ump);
  792         ump->um_fs = malloc((u_long)fs->fs_sbsize, M_UFSMNT,
  793             M_WAITOK);
  794 
  795         if (fs->fs_magic == FS_UFS1_MAGIC)
  796                 ump->um_fstype = UM_UFS1;
  797 #ifdef FFS2
  798         else
  799                 ump->um_fstype = UM_UFS2;
  800 #endif
  801 
  802         bcopy(bp->b_data, ump->um_fs, (u_int)fs->fs_sbsize);
  803         if (fs->fs_sbsize < SBSIZE)
  804                 bp->b_flags |= B_INVAL;
  805         brelse(bp);
  806         bp = NULL;
  807         fs = ump->um_fs;
  808 
  809         ffs1_compat_read(fs, ump, sbloc);
  810 
  811         if (fs->fs_clean == 0)
  812                 fs->fs_flags |= FS_UNCLEAN;
  813         fs->fs_ronly = ronly;
  814         size = fs->fs_cssize;
  815         blks = howmany(size, fs->fs_fsize);
  816         if (fs->fs_contigsumsize > 0)
  817                 size += fs->fs_ncg * sizeof(int32_t);
  818         space = malloc((u_long)size, M_UFSMNT, M_WAITOK);
  819         fs->fs_csp = (struct csum *)space;
  820         for (i = 0; i < blks; i += fs->fs_frag) {
  821                 size = fs->fs_bsize;
  822                 if (i + fs->fs_frag > blks)
  823                         size = (blks - i) * fs->fs_fsize;
  824                 error = bread(devvp, fsbtodb(fs, fs->fs_csaddr + i), size,
  825                               cred, &bp);
  826                 if (error) {
  827                         free(fs->fs_csp, M_UFSMNT);
  828                         goto out;
  829                 }
  830                 bcopy(bp->b_data, space, (u_int)size);
  831                 space += size;
  832                 brelse(bp);
  833                 bp = NULL;
  834         }
  835         if (fs->fs_contigsumsize > 0) {
  836                 fs->fs_maxcluster = lp = (int32_t *)space;
  837                 for (i = 0; i < fs->fs_ncg; i++)
  838                         *lp++ = fs->fs_contigsumsize;
  839         }
  840         mp->mnt_data = (qaddr_t)ump;
  841         mp->mnt_stat.f_fsid.val[0] = (long)dev;
  842         /* Use on-disk fsid if it exists, else fake it */
  843         if (fs->fs_id[0] != 0 && fs->fs_id[1] != 0)
  844                 mp->mnt_stat.f_fsid.val[1] = fs->fs_id[1];
  845         else
  846                 mp->mnt_stat.f_fsid.val[1] = mp->mnt_vfc->vfc_typenum;
  847         mp->mnt_maxsymlinklen = fs->fs_maxsymlinklen;
  848         mp->mnt_flag |= MNT_LOCAL;
  849         ump->um_mountp = mp;
  850         ump->um_dev = dev;
  851         ump->um_devvp = devvp;
  852         ump->um_nindir = fs->fs_nindir;
  853         ump->um_bptrtodb = fs->fs_fsbtodb;
  854         ump->um_seqinc = fs->fs_frag;
  855         for (i = 0; i < MAXQUOTAS; i++)
  856                 ump->um_quotas[i] = NULLVP;
  857 
  858         devvp->v_specmountpoint = mp;
  859         ffs_oldfscompat(fs);
  860 
  861         if (ronly)
  862                 fs->fs_contigdirs = NULL;
  863         else {
  864                 fs->fs_contigdirs = (u_int8_t*)malloc((u_long)fs->fs_ncg,
  865                                                       M_UFSMNT, M_WAITOK);
  866                 bzero(fs->fs_contigdirs, fs->fs_ncg);
  867         }
  868 
  869         /*
  870          * Set FS local "last mounted on" information (NULL pad)
  871          */
  872         copystr(mp->mnt_stat.f_mntonname,       /* mount point*/
  873                 fs->fs_fsmnt,                   /* copy area*/
  874                 sizeof(fs->fs_fsmnt) - 1,       /* max size*/
  875                 &strsize);                      /* real size*/
  876         bzero(fs->fs_fsmnt + strsize, sizeof(fs->fs_fsmnt) - strsize);
  877 
  878 #if 0
  879         if( mp->mnt_flag & MNT_ROOTFS) {
  880                 /*
  881                  * Root mount; update timestamp in mount structure.
  882                  * this will be used by the common root mount code
  883                  * to update the system clock.
  884                  */
  885                 mp->mnt_time = fs->fs_time;
  886         }
  887 #endif
  888 
  889         /*
  890          * XXX
  891          * Limit max file size.  Even though ffs can handle files up to 16TB,
  892          * we do limit the max file to 2^31 pages to prevent overflow of
  893          * a 32-bit unsigned int.  The buffer cache has its own checks but
  894          * a little added paranoia never hurts.
  895          */
  896         ump->um_savedmaxfilesize = fs->fs_maxfilesize;          /* XXX */
  897         maxfilesize = (u_int64_t)0x80000000 * MIN(PAGE_SIZE, fs->fs_bsize) - 1;
  898         if (fs->fs_maxfilesize > maxfilesize)                   /* XXX */
  899                 fs->fs_maxfilesize = maxfilesize;               /* XXX */
  900         if (ronly == 0) {
  901                 if ((fs->fs_flags & FS_DOSOFTDEP) &&
  902                     (error = softdep_mount(devvp, mp, fs, cred)) != 0) {
  903                         free(fs->fs_csp, M_UFSMNT);
  904                         free(fs->fs_contigdirs, M_UFSMNT);
  905                         goto out;
  906                 }
  907                 fs->fs_fmod = 1;
  908                 fs->fs_clean = 0;
  909                 if (mp->mnt_flag & MNT_SOFTDEP)
  910                         fs->fs_flags |= FS_DOSOFTDEP;
  911                 else
  912                         fs->fs_flags &= ~FS_DOSOFTDEP;
  913                 (void) ffs_sbupdate(ump, MNT_WAIT);
  914         }
  915         return (0);
  916 out:
  917         devvp->v_specmountpoint = NULL;
  918         if (bp)
  919                 brelse(bp);
  920         (void)VOP_CLOSE(devvp, ronly ? FREAD : FREAD|FWRITE, cred, p);
  921         if (ump) {
  922                 free(ump->um_fs, M_UFSMNT);
  923                 free(ump, M_UFSMNT);
  924                 mp->mnt_data = (qaddr_t)0;
  925         }
  926         return (error);
  927 }
  928 
  929 /*
  930  * Sanity checks for old file systems.
  931  */
  932 int
  933 ffs_oldfscompat(struct fs *fs)
  934 {
  935         int i;
  936 
  937         fs->fs_npsect = max(fs->fs_npsect, fs->fs_nsect);       /* XXX */
  938         fs->fs_interleave = max(fs->fs_interleave, 1);          /* XXX */
  939         if (fs->fs_postblformat == FS_42POSTBLFMT)              /* XXX */
  940                 fs->fs_nrpos = 8;                               /* XXX */
  941         if (fs->fs_inodefmt < FS_44INODEFMT) {                  /* XXX */
  942                 u_int64_t sizepb = fs->fs_bsize;                /* XXX */
  943                                                                 /* XXX */
  944                 fs->fs_maxfilesize = fs->fs_bsize * NDADDR - 1; /* XXX */
  945                 for (i = 0; i < NIADDR; i++) {                  /* XXX */
  946                         sizepb *= NINDIR(fs);                   /* XXX */
  947                         fs->fs_maxfilesize += sizepb;           /* XXX */
  948                 }                                               /* XXX */
  949                 fs->fs_qbmask = ~fs->fs_bmask;                  /* XXX */
  950                 fs->fs_qfmask = ~fs->fs_fmask;                  /* XXX */
  951         }                                                       /* XXX */
  952         if (fs->fs_avgfilesize <= 0)                            /* XXX */
  953                 fs->fs_avgfilesize = AVFILESIZ;                 /* XXX */
  954         if (fs->fs_avgfpdir <= 0)                               /* XXX */
  955                 fs->fs_avgfpdir = AFPDIR;                       /* XXX */
  956         return (0);
  957 }
  958 
  959 /*
  960  * Auxiliary function for reading FFS1 super blocks.
  961  */
  962 void
  963 ffs1_compat_read(struct fs *fs, struct ufsmount *ump, daddr64_t sbloc)
  964 {
  965         if (fs->fs_magic == FS_UFS2_MAGIC)
  966                 return; /* UFS2 */
  967 #if 0
  968         if (fs->fs_ffs1_flags & FS_FLAGS_UPDATED)
  969                 return; /* Already updated */
  970 #endif
  971         fs->fs_flags = fs->fs_ffs1_flags;
  972         fs->fs_sblockloc = sbloc;
  973         fs->fs_maxbsize = fs->fs_bsize;
  974         fs->fs_time = fs->fs_ffs1_time;
  975         fs->fs_size = fs->fs_ffs1_size;
  976         fs->fs_dsize = fs->fs_ffs1_dsize;
  977         fs->fs_csaddr = fs->fs_ffs1_csaddr;
  978         fs->fs_cstotal.cs_ndir = fs->fs_ffs1_cstotal.cs_ndir;
  979         fs->fs_cstotal.cs_nbfree = fs->fs_ffs1_cstotal.cs_nbfree;
  980         fs->fs_cstotal.cs_nifree = fs->fs_ffs1_cstotal.cs_nifree;
  981         fs->fs_cstotal.cs_nffree = fs->fs_ffs1_cstotal.cs_nffree;
  982         fs->fs_ffs1_flags |= FS_FLAGS_UPDATED;
  983 }
  984 
  985 /*
  986  * Auxiliary function for writing FFS1 super blocks.
  987  */
  988 void
  989 ffs1_compat_write(struct fs *fs, struct ufsmount *ump)
  990 {
  991         if (fs->fs_magic != FS_UFS1_MAGIC)
  992                 return; /* UFS2 */
  993 
  994         fs->fs_ffs1_time = fs->fs_time;
  995         fs->fs_ffs1_cstotal.cs_ndir = fs->fs_cstotal.cs_ndir;
  996         fs->fs_ffs1_cstotal.cs_nbfree = fs->fs_cstotal.cs_nbfree;
  997         fs->fs_ffs1_cstotal.cs_nifree = fs->fs_cstotal.cs_nifree;
  998         fs->fs_ffs1_cstotal.cs_nffree = fs->fs_cstotal.cs_nffree;
  999 }
 1000 
 1001 /*
 1002  * unmount system call
 1003  */
 1004 int
 1005 ffs_unmount(struct mount *mp, int mntflags, struct proc *p)
 1006 {
 1007         struct ufsmount *ump;
 1008         struct fs *fs;
 1009         int error, flags;
 1010 
 1011         flags = 0;
 1012         if (mntflags & MNT_FORCE)
 1013                 flags |= FORCECLOSE;
 1014 
 1015         ump = VFSTOUFS(mp);
 1016         fs = ump->um_fs;
 1017         if (mp->mnt_flag & MNT_SOFTDEP)
 1018                 error = softdep_flushfiles(mp, flags, p);
 1019         else
 1020                 error = ffs_flushfiles(mp, flags, p);
 1021         if (error != 0)
 1022                 return (error);
 1023 
 1024         if (fs->fs_ronly == 0) {
 1025                 fs->fs_clean = (fs->fs_flags & FS_UNCLEAN) ? 0 : 1;
 1026                 error = ffs_sbupdate(ump, MNT_WAIT);
 1027                 /* ignore write errors if mounted RW on read-only device */
 1028                 if (error && error != EROFS) {
 1029                         fs->fs_clean = 0;
 1030                         return (error);
 1031                 }
 1032                 free(fs->fs_contigdirs, M_UFSMNT);
 1033         }
 1034         ump->um_devvp->v_specmountpoint = NULL;
 1035 
 1036         vinvalbuf(ump->um_devvp, V_SAVE, NOCRED, p, 0, 0);
 1037         error = VOP_CLOSE(ump->um_devvp, fs->fs_ronly ? FREAD : FREAD|FWRITE,
 1038                 NOCRED, p);
 1039         vrele(ump->um_devvp);
 1040         free(fs->fs_csp, M_UFSMNT);
 1041         free(fs, M_UFSMNT);
 1042         free(ump, M_UFSMNT);
 1043         mp->mnt_data = (qaddr_t)0;
 1044         mp->mnt_flag &= ~MNT_LOCAL;
 1045         return (error);
 1046 }
 1047 
 1048 /*
 1049  * Flush out all the files in a filesystem.
 1050  */
 1051 int
 1052 ffs_flushfiles(struct mount *mp, int flags, struct proc *p)
 1053 {
 1054         struct ufsmount *ump;
 1055         int error;
 1056 
 1057         ump = VFSTOUFS(mp);
 1058         if (mp->mnt_flag & MNT_QUOTA) {
 1059                 int i;
 1060                 if ((error = vflush(mp, NULLVP, SKIPSYSTEM|flags)) != 0)
 1061                         return (error);
 1062                 for (i = 0; i < MAXQUOTAS; i++) {
 1063                         if (ump->um_quotas[i] == NULLVP)
 1064                                 continue;
 1065                         quotaoff(p, mp, i);
 1066                 }
 1067                 /*
 1068                  * Here we fall through to vflush again to ensure
 1069                  * that we have gotten rid of all the system vnodes.
 1070                  */
 1071         }
 1072 
 1073         /*
 1074          * Flush all the files.
 1075          */
 1076         if ((error = vflush(mp, NULL, flags)) != 0)
 1077                 return (error);
 1078         /*
 1079          * Flush filesystem metadata.
 1080          */
 1081         vn_lock(ump->um_devvp, LK_EXCLUSIVE | LK_RETRY, p);
 1082         error = VOP_FSYNC(ump->um_devvp, p->p_ucred, MNT_WAIT, p);
 1083         VOP_UNLOCK(ump->um_devvp, 0, p);
 1084         return (error);
 1085 }
 1086 
 1087 /*
 1088  * Get file system statistics.
 1089  */
 1090 int
 1091 ffs_statfs(struct mount *mp, struct statfs *sbp, struct proc *p)
 1092 {
 1093         struct ufsmount *ump;
 1094         struct fs *fs;
 1095 
 1096         ump = VFSTOUFS(mp);
 1097         fs = ump->um_fs;
 1098 
 1099 #ifdef FFS2
 1100         if (fs->fs_magic != FS_MAGIC && fs->fs_magic != FS_UFS2_MAGIC)
 1101                 panic("ffs_statfs");
 1102 #else
 1103         if (fs->fs_magic != FS_MAGIC)
 1104                 panic("ffs_statfs");
 1105 #endif /* FFS2 */
 1106 
 1107         sbp->f_bsize = fs->fs_fsize;
 1108         sbp->f_iosize = fs->fs_bsize;
 1109         sbp->f_blocks = fs->fs_dsize;
 1110         sbp->f_bfree = fs->fs_cstotal.cs_nbfree * fs->fs_frag +
 1111                 fs->fs_cstotal.cs_nffree;
 1112         sbp->f_bavail = sbp->f_bfree - ((int64_t)fs->fs_dsize * fs->fs_minfree / 100);
 1113         sbp->f_files = fs->fs_ncg * fs->fs_ipg - ROOTINO;
 1114         sbp->f_ffree = fs->fs_cstotal.cs_nifree;
 1115         if (sbp != &mp->mnt_stat) {
 1116                 bcopy(mp->mnt_stat.f_mntonname, sbp->f_mntonname, MNAMELEN);
 1117                 bcopy(mp->mnt_stat.f_mntfromname, sbp->f_mntfromname, MNAMELEN);
 1118                 bcopy(&mp->mnt_stat.mount_info.ufs_args,
 1119                     &sbp->mount_info.ufs_args, sizeof(struct ufs_args));
 1120         }
 1121         strncpy(sbp->f_fstypename, mp->mnt_vfc->vfc_name, MFSNAMELEN);
 1122 
 1123         return (0);
 1124 }
 1125 
 1126 struct ffs_sync_args {
 1127         int allerror;
 1128         struct proc *p;
 1129         int waitfor;
 1130         struct ucred *cred;
 1131 };
 1132 
 1133 int
 1134 ffs_sync_vnode(struct vnode *vp, void *arg) {
 1135         struct ffs_sync_args *fsa = arg;
 1136         struct inode *ip;
 1137         int error;
 1138 
 1139         ip = VTOI(vp);
 1140         if (vp->v_type == VNON || 
 1141             ((ip->i_flag &
 1142                 (IN_ACCESS | IN_CHANGE | IN_MODIFIED | IN_UPDATE)) == 0 &&
 1143                 LIST_EMPTY(&vp->v_dirtyblkhd)) ) {
 1144                 return (0);
 1145         }
 1146 
 1147         if (vget(vp, LK_EXCLUSIVE | LK_NOWAIT, fsa->p))
 1148                 return (0);
 1149 
 1150         if ((error = VOP_FSYNC(vp, fsa->cred, fsa->waitfor, fsa->p)))
 1151                 fsa->allerror = error;
 1152         VOP_UNLOCK(vp, 0, fsa->p);
 1153         vrele(vp);
 1154 
 1155         return (0);
 1156 }
 1157 
 1158 /*
 1159  * Go through the disk queues to initiate sandbagged IO;
 1160  * go through the inodes to write those that have been modified;
 1161  * initiate the writing of the super block if it has been modified.
 1162  *
 1163  * Should always be called with the mount point locked.
 1164  */
 1165 int
 1166 ffs_sync(struct mount *mp, int waitfor, struct ucred *cred, struct proc *p)
 1167 {
 1168         struct ufsmount *ump = VFSTOUFS(mp);
 1169         struct fs *fs;
 1170         int error, allerror = 0, count;
 1171         struct ffs_sync_args fsa;
 1172 
 1173         fs = ump->um_fs;
 1174         /*
 1175          * Write back modified superblock.
 1176          * Consistency check that the superblock
 1177          * is still in the buffer cache.
 1178          */
 1179         if (fs->fs_fmod != 0 && fs->fs_ronly != 0) {
 1180                 printf("fs = %s\n", fs->fs_fsmnt);
 1181                 panic("update: rofs mod");
 1182         }
 1183  loop:
 1184         /*
 1185          * Write back each (modified) inode.
 1186          */
 1187         fsa.allerror = 0;
 1188         fsa.p = p;
 1189         fsa.cred = cred;
 1190         fsa.waitfor = waitfor;
 1191 
 1192         /*
 1193          * Don't traverse the vnode list if we want to skip all of them.
 1194          */
 1195         if (waitfor != MNT_LAZY) {
 1196                 vfs_mount_foreach_vnode(mp, ffs_sync_vnode, &fsa);
 1197                 allerror = fsa.allerror;
 1198         }
 1199 
 1200         /*
 1201          * Force stale file system control information to be flushed.
 1202          */
 1203         if ((ump->um_mountp->mnt_flag & MNT_SOFTDEP) && waitfor == MNT_WAIT) {
 1204                 if ((error = softdep_flushworklist(ump->um_mountp, &count, p)))
 1205                         allerror = error;
 1206                 /* Flushed work items may create new vnodes to clean */
 1207                 if (count) 
 1208                         goto loop;
 1209         }
 1210         if (waitfor != MNT_LAZY) {
 1211                 vn_lock(ump->um_devvp, LK_EXCLUSIVE | LK_RETRY, p);
 1212                 if ((error = VOP_FSYNC(ump->um_devvp, cred, waitfor, p)) != 0)
 1213                         allerror = error;
 1214                 VOP_UNLOCK(ump->um_devvp, 0, p);
 1215         }
 1216         qsync(mp);
 1217         /*
 1218          * Write back modified superblock.
 1219          */
 1220 
 1221         if (fs->fs_fmod != 0 && (error = ffs_sbupdate(ump, waitfor)) != 0)
 1222                 allerror = error;
 1223 
 1224         return (allerror);
 1225 }
 1226 
 1227 /*
 1228  * Look up a FFS dinode number to find its incore vnode, otherwise read it
 1229  * in from disk.  If it is in core, wait for the lock bit to clear, then
 1230  * return the inode locked.  Detection and handling of mount points must be
 1231  * done by the calling routine.
 1232  */
 1233 int
 1234 ffs_vget(struct mount *mp, ino_t ino, struct vnode **vpp)
 1235 {
 1236         struct fs *fs;
 1237         struct inode *ip;
 1238         struct ufs1_dinode *dp1;
 1239 #ifdef FFS2
 1240         struct ufs2_dinode *dp2;
 1241 #endif
 1242         struct ufsmount *ump;
 1243         struct buf *bp;
 1244         struct vnode *vp;
 1245         dev_t dev;
 1246         int error;
 1247 
 1248         ump = VFSTOUFS(mp);
 1249         dev = ump->um_dev;
 1250 retry:
 1251         if ((*vpp = ufs_ihashget(dev, ino)) != NULL)
 1252                 return (0);
 1253 
 1254         /* Allocate a new vnode/inode. */
 1255         if ((error = getnewvnode(VT_UFS, mp, ffs_vnodeop_p, &vp)) != 0) {
 1256                 *vpp = NULL;
 1257                 return (error);
 1258         }
 1259 #ifdef VFSDEBUG
 1260         vp->v_flag |= VLOCKSWORK;
 1261 #endif
 1262         /* XXX - we use the same pool for ffs and mfs */
 1263         ip = pool_get(&ffs_ino_pool, PR_WAITOK);
 1264         bzero((caddr_t)ip, sizeof(struct inode));
 1265         lockinit(&ip->i_lock, PINOD, "inode", 0, 0);
 1266         ip->i_ump = ump;
 1267         VREF(ip->i_devvp);
 1268         vp->v_data = ip;
 1269         ip->i_vnode = vp;
 1270         ip->i_fs = fs = ump->um_fs;
 1271         ip->i_dev = dev;
 1272         ip->i_number = ino;
 1273         ip->i_vtbl = &ffs_vtbl;
 1274 
 1275         /*
 1276          * Put it onto its hash chain and lock it so that other requests for
 1277          * this inode will block if they arrive while we are sleeping waiting
 1278          * for old data structures to be purged or for the contents of the
 1279          * disk portion of this inode to be read.
 1280          */
 1281         error = ufs_ihashins(ip);
 1282         
 1283         if (error) {
 1284                 /*
 1285                  * VOP_INACTIVE will treat this as a stale file
 1286                  * and recycle it quickly
 1287                  */
 1288                 vrele(vp);
 1289 
 1290                 if (error == EEXIST)
 1291                         goto retry;
 1292 
 1293                 return (error);
 1294         }
 1295 
 1296 
 1297         /* Read in the disk contents for the inode, copy into the inode. */
 1298         error = bread(ump->um_devvp, fsbtodb(fs, ino_to_fsba(fs, ino)),
 1299                       (int)fs->fs_bsize, NOCRED, &bp);
 1300         if (error) {
 1301                 /*
 1302                  * The inode does not contain anything useful, so it would
 1303                  * be misleading to leave it on its hash chain. With mode
 1304                  * still zero, it will be unlinked and returned to the free
 1305                  * list by vput().
 1306                  */
 1307                 vput(vp);
 1308                 brelse(bp);
 1309                 *vpp = NULL;
 1310                 return (error);
 1311         }
 1312 
 1313 #ifdef FFS2
 1314         if (ip->i_ump->um_fstype == UM_UFS2) {
 1315                 ip->i_din2 = pool_get(&ffs_dinode2_pool, PR_WAITOK);
 1316                 dp2 = (struct ufs2_dinode *) bp->b_data + ino_to_fsbo(fs, ino);
 1317                 *ip->i_din2 = *dp2;
 1318         } else
 1319 #endif
 1320         {
 1321                 ip->i_din1 = pool_get(&ffs_dinode1_pool, PR_WAITOK);
 1322                 dp1 = (struct ufs1_dinode *) bp->b_data + ino_to_fsbo(fs, ino);
 1323                 *ip->i_din1 = *dp1;
 1324         }
 1325 
 1326         brelse(bp);
 1327 
 1328         if (DOINGSOFTDEP(vp))
 1329                 softdep_load_inodeblock(ip);
 1330         else
 1331                 ip->i_effnlink = DIP(ip, nlink);
 1332 
 1333         /*
 1334          * Initialize the vnode from the inode, check for aliases.
 1335          * Note that the underlying vnode may have changed.
 1336          */
 1337         error = ufs_vinit(mp, ffs_specop_p, FFS_FIFOOPS, &vp);
 1338         if (error) {
 1339                 vput(vp);
 1340                 *vpp = NULL;
 1341                 return (error);
 1342         }
 1343 
 1344         /*
 1345          * Set up a generation number for this inode if it does not
 1346          * already have one. This should only happen on old filesystems.
 1347          */
 1348         if (DIP(ip, gen) == 0) {
 1349                 DIP_ASSIGN(ip, gen, arc4random() & INT_MAX);
 1350                 if (DIP(ip, gen) == 0 || DIP(ip, gen) == -1)
 1351                         DIP_ASSIGN(ip, gen, 1); /* Shouldn't happen */
 1352                 if ((vp->v_mount->mnt_flag & MNT_RDONLY) == 0)
 1353                         ip->i_flag |= IN_MODIFIED;
 1354         }
 1355 
 1356         /*
 1357          * Ensure that uid and gid are correct. This is a temporary
 1358          * fix until fsck has been changed to do the update.
 1359          */
 1360         if (fs->fs_magic == FS_UFS1_MAGIC && fs->fs_inodefmt < FS_44INODEFMT) {
 1361                 ip->i_ffs1_uid = ip->i_din1->di_ouid;
 1362                 ip->i_ffs1_gid = ip->i_din1->di_ogid;
 1363         }
 1364 
 1365         *vpp = vp;
 1366 
 1367         return (0);
 1368 }
 1369 
 1370 /*
 1371  * File handle to vnode
 1372  *
 1373  * Have to be really careful about stale file handles:
 1374  * - check that the inode number is valid
 1375  * - call ffs_vget() to get the locked inode
 1376  * - check for an unallocated inode (i_mode == 0)
 1377  */
 1378 int
 1379 ffs_fhtovp(struct mount *mp, struct fid *fhp, struct vnode **vpp)
 1380 {
 1381         struct ufid *ufhp;
 1382         struct fs *fs;
 1383 
 1384         ufhp = (struct ufid *)fhp;
 1385         fs = VFSTOUFS(mp)->um_fs;
 1386         if (ufhp->ufid_ino < ROOTINO ||
 1387             ufhp->ufid_ino >= fs->fs_ncg * fs->fs_ipg)
 1388                 return (ESTALE);
 1389         return (ufs_fhtovp(mp, ufhp, vpp));
 1390 }
 1391 
 1392 /*
 1393  * Vnode pointer to File handle
 1394  */
 1395 /* ARGSUSED */
 1396 int
 1397 ffs_vptofh(struct vnode *vp, struct fid *fhp)
 1398 {
 1399         struct inode *ip;
 1400         struct ufid *ufhp;
 1401 
 1402         ip = VTOI(vp);
 1403         ufhp = (struct ufid *)fhp;
 1404         ufhp->ufid_len = sizeof(struct ufid);
 1405         ufhp->ufid_ino = ip->i_number;
 1406         ufhp->ufid_gen = DIP(ip, gen);
 1407 
 1408         return (0);
 1409 }
 1410 
 1411 /*
 1412  * Write a superblock and associated information back to disk.
 1413  */
 1414 int
 1415 ffs_sbupdate(struct ufsmount *mp, int waitfor)
 1416 {
 1417         struct fs *dfs, *fs = mp->um_fs;
 1418         struct buf *bp;
 1419         int blks;
 1420         caddr_t space;
 1421         int i, size, error, allerror = 0;
 1422 
 1423         /*
 1424          * First write back the summary information.
 1425          */
 1426         blks = howmany(fs->fs_cssize, fs->fs_fsize);
 1427         space = (caddr_t)fs->fs_csp;
 1428         for (i = 0; i < blks; i += fs->fs_frag) {
 1429                 size = fs->fs_bsize;
 1430                 if (i + fs->fs_frag > blks)
 1431                         size = (blks - i) * fs->fs_fsize;
 1432                 bp = getblk(mp->um_devvp, fsbtodb(fs, fs->fs_csaddr + i),
 1433                             size, 0, 0);
 1434                 bcopy(space, bp->b_data, (u_int)size);
 1435                 space += size;
 1436                 if (waitfor != MNT_WAIT)
 1437                         bawrite(bp);
 1438                 else if ((error = bwrite(bp)))
 1439                         allerror = error;
 1440         }
 1441 
 1442         /*
 1443          * Now write back the superblock itself. If any errors occurred
 1444          * up to this point, then fail so that the superblock avoids
 1445          * being written out as clean.
 1446          */
 1447         if (allerror) {
 1448                 return (allerror);
 1449         }
 1450 
 1451         bp = getblk(mp->um_devvp,
 1452             fs->fs_sblockloc >> (fs->fs_fshift - fs->fs_fsbtodb),
 1453             (int)fs->fs_sbsize, 0, 0);
 1454         fs->fs_fmod = 0;
 1455         fs->fs_time = time_second;
 1456         bcopy((caddr_t)fs, bp->b_data, (u_int)fs->fs_sbsize);
 1457         /* Restore compatibility to old file systems.              XXX */
 1458         dfs = (struct fs *)bp->b_data;                          /* XXX */
 1459         if (fs->fs_postblformat == FS_42POSTBLFMT)              /* XXX */
 1460                 dfs->fs_nrpos = -1;                             /* XXX */
 1461         if (fs->fs_inodefmt < FS_44INODEFMT) {                  /* XXX */
 1462                 int32_t *lp, tmp;                               /* XXX */
 1463                                                                 /* XXX */
 1464                 lp = (int32_t *)&dfs->fs_qbmask;                /* XXX */
 1465                 tmp = lp[4];                                    /* XXX */
 1466                 for (i = 4; i > 0; i--)                         /* XXX */
 1467                         lp[i] = lp[i-1];                        /* XXX */
 1468                 lp[0] = tmp;                                    /* XXX */
 1469         }                                                       /* XXX */
 1470         dfs->fs_maxfilesize = mp->um_savedmaxfilesize;          /* XXX */
 1471 
 1472         ffs1_compat_write(dfs, mp);
 1473 
 1474         if (waitfor != MNT_WAIT)
 1475                 bawrite(bp);
 1476         else if ((error = bwrite(bp)))
 1477                 allerror = error;
 1478 
 1479         return (allerror);
 1480 }
 1481 
 1482 int
 1483 ffs_init(struct vfsconf *vfsp)
 1484 {
 1485         static int done;
 1486 
 1487         if (done)
 1488                 return (0);
 1489 
 1490         done = 1;
 1491 
 1492         pool_init(&ffs_ino_pool, sizeof(struct inode), 0, 0, 0, "ffsino",
 1493             &pool_allocator_nointr);
 1494         pool_init(&ffs_dinode1_pool, sizeof(struct ufs1_dinode), 0, 0, 0,
 1495             "dino1pl", &pool_allocator_nointr);
 1496 #ifdef FFS2
 1497         pool_init(&ffs_dinode2_pool, sizeof(struct ufs2_dinode), 0, 0, 0,
 1498             "dino2pl", &pool_allocator_nointr);
 1499 #endif
 1500 
 1501         softdep_initialize();
 1502 
 1503         return (ufs_init(vfsp));
 1504 }
 1505 
 1506 /*
 1507  * fast filesystem related variables.
 1508  */
 1509 int
 1510 ffs_sysctl(int *name, u_int namelen, void *oldp, size_t *oldlenp, void *newp,
 1511     size_t newlen, struct proc *p)
 1512 {
 1513         extern int doclusterread, doclusterwrite, doreallocblks, doasyncfree;
 1514 #ifdef FFS_SOFTUPDATES
 1515         extern int max_softdeps, tickdelay, stat_worklist_push;
 1516         extern int stat_blk_limit_push, stat_ino_limit_push, stat_blk_limit_hit;
 1517         extern int stat_ino_limit_hit, stat_sync_limit_hit, stat_indir_blk_ptrs;
 1518         extern int stat_inode_bitmap, stat_direct_blk_ptrs, stat_dir_entry;
 1519 #endif
 1520 
 1521         /* all sysctl names at this level are terminal */
 1522         if (namelen != 1)
 1523                 return (ENOTDIR);               /* overloaded */
 1524 
 1525         switch (name[0]) {
 1526         case FFS_CLUSTERREAD:
 1527                 return (sysctl_int(oldp, oldlenp, newp, newlen,
 1528                     &doclusterread));
 1529         case FFS_CLUSTERWRITE:
 1530                 return (sysctl_int(oldp, oldlenp, newp, newlen,
 1531                     &doclusterwrite));
 1532         case FFS_REALLOCBLKS:
 1533                 return (sysctl_int(oldp, oldlenp, newp, newlen,
 1534                     &doreallocblks));
 1535         case FFS_ASYNCFREE:
 1536                 return (sysctl_int(oldp, oldlenp, newp, newlen, &doasyncfree));
 1537 #ifdef FFS_SOFTUPDATES
 1538         case FFS_MAX_SOFTDEPS:
 1539                 return (sysctl_int(oldp, oldlenp, newp, newlen, &max_softdeps));
 1540         case FFS_SD_TICKDELAY:
 1541                 return (sysctl_int(oldp, oldlenp, newp, newlen, &tickdelay));
 1542         case FFS_SD_WORKLIST_PUSH:
 1543                 return (sysctl_rdint(oldp, oldlenp, newp, stat_worklist_push));
 1544         case FFS_SD_BLK_LIMIT_PUSH:
 1545                 return (sysctl_rdint(oldp, oldlenp, newp, stat_blk_limit_push));
 1546         case FFS_SD_INO_LIMIT_PUSH:
 1547                 return (sysctl_rdint(oldp, oldlenp, newp, stat_ino_limit_push));
 1548         case FFS_SD_BLK_LIMIT_HIT:
 1549                 return (sysctl_rdint(oldp, oldlenp, newp, stat_blk_limit_hit));
 1550         case FFS_SD_INO_LIMIT_HIT:
 1551                 return (sysctl_rdint(oldp, oldlenp, newp, stat_ino_limit_hit));
 1552         case FFS_SD_SYNC_LIMIT_HIT:
 1553                 return (sysctl_rdint(oldp, oldlenp, newp, stat_sync_limit_hit));
 1554         case FFS_SD_INDIR_BLK_PTRS:
 1555                 return (sysctl_rdint(oldp, oldlenp, newp, stat_indir_blk_ptrs));
 1556         case FFS_SD_INODE_BITMAP:
 1557                 return (sysctl_rdint(oldp, oldlenp, newp, stat_inode_bitmap));
 1558         case FFS_SD_DIRECT_BLK_PTRS:
 1559                 return (sysctl_rdint(oldp, oldlenp, newp, stat_direct_blk_ptrs));
 1560         case FFS_SD_DIR_ENTRY:
 1561                 return (sysctl_rdint(oldp, oldlenp, newp, stat_dir_entry));
 1562 #endif
 1563 #ifdef UFS_DIRHASH
 1564         case FFS_DIRHASH_DIRSIZE:
 1565                 return (sysctl_int(oldp, oldlenp, newp, newlen,
 1566                     &ufs_mindirhashsize));
 1567         case FFS_DIRHASH_MAXMEM:
 1568                 return (sysctl_int(oldp, oldlenp, newp, newlen,
 1569                     &ufs_dirhashmaxmem));
 1570         case FFS_DIRHASH_MEM:
 1571                 return (sysctl_rdint(oldp, oldlenp, newp, ufs_dirhashmem));
 1572 #endif
 1573 
 1574         default:
 1575                 return (EOPNOTSUPP);
 1576         }
 1577         /* NOTREACHED */
 1578 }

/* [<][>][^][v][top][bottom][index][help] */