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/ufs/ffs/ffs_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 /*
    2  * Copyright (c) 1989, 1991, 1993, 1994
    3  *      The Regents of the University of California.  All rights reserved.
    4  *
    5  * Redistribution and use in source and binary forms, with or without
    6  * modification, are permitted provided that the following conditions
    7  * are met:
    8  * 1. Redistributions of source code must retain the above copyright
    9  *    notice, this list of conditions and the following disclaimer.
   10  * 2. Redistributions in binary form must reproduce the above copyright
   11  *    notice, this list of conditions and the following disclaimer in the
   12  *    documentation and/or other materials provided with the distribution.
   13  * 3. All advertising materials mentioning features or use of this software
   14  *    must display the following acknowledgement:
   15  *      This product includes software developed by the University of
   16  *      California, Berkeley and its contributors.
   17  * 4. Neither the name of the University nor the names of its contributors
   18  *    may be used to endorse or promote products derived from this software
   19  *    without specific prior written permission.
   20  *
   21  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
   22  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
   23  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
   24  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
   25  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
   26  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
   27  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
   28  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
   29  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
   30  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   31  * SUCH DAMAGE.
   32  *
   33  *      @(#)ffs_vfsops.c        8.31 (Berkeley) 5/20/95
   34  */
   35 
   36 #include <sys/cdefs.h>
   37 __FBSDID("$FreeBSD: releng/5.2/sys/ufs/ffs/ffs_vfsops.c 123482 2003-12-12 02:23:22Z truckman $");
   38 
   39 #include "opt_mac.h"
   40 #include "opt_quota.h"
   41 #include "opt_ufs.h"
   42 
   43 #include <sys/param.h>
   44 #include <sys/systm.h>
   45 #include <sys/namei.h>
   46 #include <sys/proc.h>
   47 #include <sys/kernel.h>
   48 #include <sys/mac.h>
   49 #include <sys/vnode.h>
   50 #include <sys/mount.h>
   51 #include <sys/bio.h>
   52 #include <sys/buf.h>
   53 #include <sys/conf.h>
   54 #include <sys/fcntl.h>
   55 #include <sys/disk.h>
   56 #include <sys/malloc.h>
   57 #include <sys/mutex.h>
   58 
   59 #include <ufs/ufs/extattr.h>
   60 #include <ufs/ufs/quota.h>
   61 #include <ufs/ufs/ufsmount.h>
   62 #include <ufs/ufs/inode.h>
   63 #include <ufs/ufs/ufs_extern.h>
   64 
   65 #include <ufs/ffs/fs.h>
   66 #include <ufs/ffs/ffs_extern.h>
   67 
   68 #include <vm/vm.h>
   69 #include <vm/uma.h>
   70 #include <vm/vm_page.h>
   71 
   72 uma_zone_t uma_inode, uma_ufs1, uma_ufs2;
   73 
   74 static int      ffs_sbupdate(struct ufsmount *, int);
   75        int      ffs_reload(struct mount *,struct ucred *,struct thread *);
   76 static int      ffs_mountfs(struct vnode *, struct mount *, struct thread *);
   77 static void     ffs_oldfscompat_read(struct fs *, struct ufsmount *,
   78                     ufs2_daddr_t);
   79 static void     ffs_oldfscompat_write(struct fs *, struct ufsmount *);
   80 static void     ffs_ifree(struct ufsmount *ump, struct inode *ip);
   81 static vfs_init_t ffs_init;
   82 static vfs_uninit_t ffs_uninit;
   83 static vfs_extattrctl_t ffs_extattrctl;
   84 
   85 static struct vfsops ufs_vfsops = {
   86         .vfs_extattrctl =       ffs_extattrctl,
   87         .vfs_fhtovp =           ffs_fhtovp,
   88         .vfs_init =             ffs_init,
   89         .vfs_mount =            ffs_mount,
   90         .vfs_quotactl =         ufs_quotactl,
   91         .vfs_root =             ufs_root,
   92         .vfs_start =            ufs_start,
   93         .vfs_statfs =           ffs_statfs,
   94         .vfs_sync =             ffs_sync,
   95         .vfs_uninit =           ffs_uninit,
   96         .vfs_unmount =          ffs_unmount,
   97         .vfs_vget =             ffs_vget,
   98         .vfs_vptofh =           ffs_vptofh,
   99 };
  100 
  101 VFS_SET(ufs_vfsops, ufs, 0);
  102 
  103 /*
  104  * ffs_mount
  105  *
  106  * Called when mounting local physical media
  107  *
  108  * PARAMETERS:
  109  *              mountroot
  110  *                      mp      mount point structure
  111  *                      path    NULL (flag for root mount!!!)
  112  *                      data    <unused>
  113  *                      ndp     <unused>
  114  *                      p       process (user credentials check [statfs])
  115  *
  116  *              mount
  117  *                      mp      mount point structure
  118  *                      path    path to mount point
  119  *                      data    pointer to argument struct in user space
  120  *                      ndp     mount point namei() return (used for
  121  *                              credentials on reload), reused to look
  122  *                              up block device.
  123  *                      p       process (user credentials check)
  124  *
  125  * RETURNS:     0       Success
  126  *              !0      error number (errno.h)
  127  *
  128  * LOCK STATE:
  129  *
  130  *              ENTRY
  131  *                      mount point is locked
  132  *              EXIT
  133  *                      mount point is locked
  134  *
  135  * NOTES:
  136  *              A NULL path can be used for a flag since the mount
  137  *              system call will fail with EFAULT in copyinstr in
  138  *              namei() if it is a genuine NULL from the user.
  139  */
  140 int
  141 ffs_mount(mp, path, data, ndp, td)
  142         struct mount            *mp;    /* mount struct pointer*/
  143         char                    *path;  /* path to mount point*/
  144         caddr_t                 data;   /* arguments to FS specific mount*/
  145         struct nameidata        *ndp;   /* mount point credentials*/
  146         struct thread           *td;    /* process requesting mount*/
  147 {
  148         size_t size;
  149         struct vnode *devvp;
  150         struct ufs_args args;
  151         struct ufsmount *ump = 0;
  152         struct fs *fs;
  153         int error, flags;
  154         mode_t accessmode;
  155 
  156         if (uma_inode == NULL) {
  157                 uma_inode = uma_zcreate("FFS inode",
  158                     sizeof(struct inode), NULL, NULL, NULL, NULL,
  159                     UMA_ALIGN_PTR, 0);
  160                 uma_ufs1 = uma_zcreate("FFS1 dinode",
  161                     sizeof(struct ufs1_dinode), NULL, NULL, NULL, NULL,
  162                     UMA_ALIGN_PTR, 0);
  163                 uma_ufs2 = uma_zcreate("FFS2 dinode",
  164                     sizeof(struct ufs2_dinode), NULL, NULL, NULL, NULL,
  165                     UMA_ALIGN_PTR, 0);
  166         }
  167         /*
  168          * Use NULL path to indicate we are mounting the root filesystem.
  169          */
  170         if (path == NULL) {
  171                 if ((error = bdevvp(rootdev, &rootvp))) {
  172                         printf("ffs_mountroot: can't find rootvp\n");
  173                         return (error);
  174                 }
  175 
  176                 if ((error = ffs_mountfs(rootvp, mp, td)) != 0)
  177                         return (error);
  178                 (void)VFS_STATFS(mp, &mp->mnt_stat, td);
  179                 return (0);
  180         }
  181 
  182         /*
  183          * Mounting non-root filesystem or updating a filesystem
  184          */
  185         if ((error = copyin(data, (caddr_t)&args, sizeof(struct ufs_args)))!= 0)
  186                 return (error);
  187 
  188         /*
  189          * If updating, check whether changing from read-only to
  190          * read/write; if there is no device name, that's all we do.
  191          */
  192         if (mp->mnt_flag & MNT_UPDATE) {
  193                 ump = VFSTOUFS(mp);
  194                 fs = ump->um_fs;
  195                 devvp = ump->um_devvp;
  196                 if (fs->fs_ronly == 0 && (mp->mnt_flag & MNT_RDONLY)) {
  197                         if ((error = vn_start_write(NULL, &mp, V_WAIT)) != 0)
  198                                 return (error);
  199                         /*
  200                          * Flush any dirty data.
  201                          */
  202                         if ((error = VFS_SYNC(mp, MNT_WAIT,
  203                             td->td_ucred, td)) != 0) {
  204                                 vn_finished_write(mp);
  205                                 return (error);
  206                         }
  207                         /*
  208                          * Check for and optionally get rid of files open
  209                          * for writing.
  210                          */
  211                         flags = WRITECLOSE;
  212                         if (mp->mnt_flag & MNT_FORCE)
  213                                 flags |= FORCECLOSE;
  214                         if (mp->mnt_flag & MNT_SOFTDEP) {
  215                                 error = softdep_flushfiles(mp, flags, td);
  216                         } else {
  217                                 error = ffs_flushfiles(mp, flags, td);
  218                         }
  219                         if (error) {
  220                                 vn_finished_write(mp);
  221                                 return (error);
  222                         }
  223                         if (fs->fs_pendingblocks != 0 ||
  224                             fs->fs_pendinginodes != 0) {
  225                                 printf("%s: %s: blocks %jd files %d\n",
  226                                     fs->fs_fsmnt, "update error",
  227                                     (intmax_t)fs->fs_pendingblocks,
  228                                     fs->fs_pendinginodes);
  229                                 fs->fs_pendingblocks = 0;
  230                                 fs->fs_pendinginodes = 0;
  231                         }
  232                         fs->fs_ronly = 1;
  233                         if ((fs->fs_flags & (FS_UNCLEAN | FS_NEEDSFSCK)) == 0)
  234                                 fs->fs_clean = 1;
  235                         if ((error = ffs_sbupdate(ump, MNT_WAIT)) != 0) {
  236                                 fs->fs_ronly = 0;
  237                                 fs->fs_clean = 0;
  238                                 vn_finished_write(mp);
  239                                 return (error);
  240                         }
  241                         vn_finished_write(mp);
  242                 }
  243                 if ((mp->mnt_flag & MNT_RELOAD) &&
  244                     (error = ffs_reload(mp, ndp->ni_cnd.cn_cred, td)) != 0)
  245                         return (error);
  246                 if (fs->fs_ronly && (mp->mnt_kern_flag & MNTK_WANTRDWR)) {
  247                         /*
  248                          * If upgrade to read-write by non-root, then verify
  249                          * that user has necessary permissions on the device.
  250                          */
  251                         if (suser(td)) {
  252                                 vn_lock(devvp, LK_EXCLUSIVE | LK_RETRY, td);
  253                                 if ((error = VOP_ACCESS(devvp, VREAD | VWRITE,
  254                                     td->td_ucred, td)) != 0) {
  255                                         VOP_UNLOCK(devvp, 0, td);
  256                                         return (error);
  257                                 }
  258                                 VOP_UNLOCK(devvp, 0, td);
  259                         }
  260                         fs->fs_flags &= ~FS_UNCLEAN;
  261                         if (fs->fs_clean == 0) {
  262                                 fs->fs_flags |= FS_UNCLEAN;
  263                                 if ((mp->mnt_flag & MNT_FORCE) ||
  264                                     ((fs->fs_flags & FS_NEEDSFSCK) == 0 &&
  265                                      (fs->fs_flags & FS_DOSOFTDEP))) {
  266                                         printf("WARNING: %s was not %s\n",
  267                                            fs->fs_fsmnt, "properly dismounted");
  268                                 } else {
  269                                         printf(
  270 "WARNING: R/W mount of %s denied.  Filesystem is not clean - run fsck\n",
  271                                             fs->fs_fsmnt);
  272                                         return (EPERM);
  273                                 }
  274                         }
  275                         if ((error = vn_start_write(NULL, &mp, V_WAIT)) != 0)
  276                                 return (error);
  277                         fs->fs_ronly = 0;
  278                         fs->fs_clean = 0;
  279                         if ((error = ffs_sbupdate(ump, MNT_WAIT)) != 0) {
  280                                 vn_finished_write(mp);
  281                                 return (error);
  282                         }
  283                         /* check to see if we need to start softdep */
  284                         if ((fs->fs_flags & FS_DOSOFTDEP) &&
  285                             (error = softdep_mount(devvp, mp, fs, td->td_ucred))){
  286                                 vn_finished_write(mp);
  287                                 return (error);
  288                         }
  289                         if (fs->fs_snapinum[0] != 0)
  290                                 ffs_snapshot_mount(mp);
  291                         vn_finished_write(mp);
  292                 }
  293                 /*
  294                  * Soft updates is incompatible with "async",
  295                  * so if we are doing softupdates stop the user
  296                  * from setting the async flag in an update.
  297                  * Softdep_mount() clears it in an initial mount 
  298                  * or ro->rw remount.
  299                  */
  300                 if (mp->mnt_flag & MNT_SOFTDEP)
  301                         mp->mnt_flag &= ~MNT_ASYNC;
  302                 /*
  303                  * If not updating name, process export requests.
  304                  */
  305                 if (args.fspec == 0)
  306                         return (vfs_export(mp, &args.export));
  307                 /*
  308                  * If this is a snapshot request, take the snapshot.
  309                  */
  310                 if (mp->mnt_flag & MNT_SNAPSHOT)
  311                         return (ffs_snapshot(mp, args.fspec));
  312         }
  313 
  314         /*
  315          * Not an update, or updating the name: look up the name
  316          * and verify that it refers to a sensible block device.
  317          */
  318         NDINIT(ndp, LOOKUP, FOLLOW, UIO_USERSPACE, args.fspec, td);
  319         if ((error = namei(ndp)) != 0)
  320                 return (error);
  321         NDFREE(ndp, NDF_ONLY_PNBUF);
  322         devvp = ndp->ni_vp;
  323         if (!vn_isdisk(devvp, &error)) {
  324                 vrele(devvp);
  325                 return (error);
  326         }
  327 
  328         /*
  329          * If mount by non-root, then verify that user has necessary
  330          * permissions on the device.
  331          */
  332         if (suser(td)) {
  333                 accessmode = VREAD;
  334                 if ((mp->mnt_flag & MNT_RDONLY) == 0)
  335                         accessmode |= VWRITE;
  336                 vn_lock(devvp, LK_EXCLUSIVE | LK_RETRY, td);
  337                 if ((error = VOP_ACCESS(devvp, accessmode, td->td_ucred, td))!= 0){
  338                         vput(devvp);
  339                         return (error);
  340                 }
  341                 VOP_UNLOCK(devvp, 0, td);
  342         }
  343 
  344         if (mp->mnt_flag & MNT_UPDATE) {
  345                 /*
  346                  * Update only
  347                  *
  348                  * If it's not the same vnode, or at least the same device
  349                  * then it's not correct.
  350                  */
  351 
  352                 if (devvp != ump->um_devvp &&
  353                     devvp->v_rdev != ump->um_devvp->v_rdev)
  354                         error = EINVAL; /* needs translation */
  355                 vrele(devvp);
  356                 if (error)
  357                         return (error);
  358         } else {
  359                 /*
  360                  * New mount
  361                  *
  362                  * We need the name for the mount point (also used for
  363                  * "last mounted on") copied in. If an error occurs,
  364                  * the mount point is discarded by the upper level code.
  365                  * Note that vfs_mount() populates f_mntonname for us.
  366                  */
  367                 if ((error = ffs_mountfs(devvp, mp, td)) != 0) {
  368                         vrele(devvp);
  369                         return (error);
  370                 }
  371         }
  372         /*
  373          * Save "mounted from" device name info for mount point (NULL pad).
  374          */
  375         copyinstr(args.fspec, mp->mnt_stat.f_mntfromname, MNAMELEN - 1, &size);
  376         bzero( mp->mnt_stat.f_mntfromname + size, MNAMELEN - size);
  377         /*
  378          * Initialize filesystem stat information in mount struct.
  379          */
  380         (void)VFS_STATFS(mp, &mp->mnt_stat, td);
  381         return (0);
  382 }
  383 
  384 /*
  385  * Reload all incore data for a filesystem (used after running fsck on
  386  * the root filesystem and finding things to fix). The filesystem must
  387  * be mounted read-only.
  388  *
  389  * Things to do to update the mount:
  390  *      1) invalidate all cached meta-data.
  391  *      2) re-read superblock from disk.
  392  *      3) re-read summary information from disk.
  393  *      4) invalidate all inactive vnodes.
  394  *      5) invalidate all cached file data.
  395  *      6) re-read inode data for all active vnodes.
  396  */
  397 int
  398 ffs_reload(mp, cred, td)
  399         struct mount *mp;
  400         struct ucred *cred;
  401         struct thread *td;
  402 {
  403         struct vnode *vp, *nvp, *devvp;
  404         struct inode *ip;
  405         void *space;
  406         struct buf *bp;
  407         struct fs *fs, *newfs;
  408         ufs2_daddr_t sblockloc;
  409         int i, blks, size, error;
  410         int32_t *lp;
  411 
  412         if ((mp->mnt_flag & MNT_RDONLY) == 0)
  413                 return (EINVAL);
  414         /*
  415          * Step 1: invalidate all cached meta-data.
  416          */
  417         devvp = VFSTOUFS(mp)->um_devvp;
  418         vn_lock(devvp, LK_EXCLUSIVE | LK_RETRY, td);
  419         error = vinvalbuf(devvp, 0, cred, td, 0, 0);
  420         VOP_UNLOCK(devvp, 0, td);
  421         if (error)
  422                 panic("ffs_reload: dirty1");
  423 
  424         /*
  425          * Only VMIO the backing device if the backing device is a real
  426          * block device.
  427          */
  428         if (vn_isdisk(devvp, NULL)) {
  429                 vn_lock(devvp, LK_EXCLUSIVE | LK_RETRY, td);
  430                 vfs_object_create(devvp, td, td->td_ucred);
  431                 VOP_UNLOCK(devvp, 0, td);
  432         }
  433 
  434         /*
  435          * Step 2: re-read superblock from disk.
  436          */
  437         fs = VFSTOUFS(mp)->um_fs;
  438         if ((error = bread(devvp, btodb(fs->fs_sblockloc), fs->fs_sbsize,
  439             NOCRED, &bp)) != 0)
  440                 return (error);
  441         newfs = (struct fs *)bp->b_data;
  442         if ((newfs->fs_magic != FS_UFS1_MAGIC &&
  443              newfs->fs_magic != FS_UFS2_MAGIC) ||
  444             newfs->fs_bsize > MAXBSIZE ||
  445             newfs->fs_bsize < sizeof(struct fs)) {
  446                         brelse(bp);
  447                         return (EIO);           /* XXX needs translation */
  448         }
  449         /*
  450          * Copy pointer fields back into superblock before copying in   XXX
  451          * new superblock. These should really be in the ufsmount.      XXX
  452          * Note that important parameters (eg fs_ncg) are unchanged.
  453          */
  454         newfs->fs_csp = fs->fs_csp;
  455         newfs->fs_maxcluster = fs->fs_maxcluster;
  456         newfs->fs_contigdirs = fs->fs_contigdirs;
  457         newfs->fs_active = fs->fs_active;
  458         /* The file system is still read-only. */
  459         newfs->fs_ronly = 1;
  460         sblockloc = fs->fs_sblockloc;
  461         bcopy(newfs, fs, (u_int)fs->fs_sbsize);
  462         brelse(bp);
  463         mp->mnt_maxsymlinklen = fs->fs_maxsymlinklen;
  464         ffs_oldfscompat_read(fs, VFSTOUFS(mp), sblockloc);
  465         if (fs->fs_pendingblocks != 0 || fs->fs_pendinginodes != 0) {
  466                 printf("%s: reload pending error: blocks %jd files %d\n",
  467                     fs->fs_fsmnt, (intmax_t)fs->fs_pendingblocks,
  468                     fs->fs_pendinginodes);
  469                 fs->fs_pendingblocks = 0;
  470                 fs->fs_pendinginodes = 0;
  471         }
  472 
  473         /*
  474          * Step 3: re-read summary information from disk.
  475          */
  476         blks = howmany(fs->fs_cssize, fs->fs_fsize);
  477         space = fs->fs_csp;
  478         for (i = 0; i < blks; i += fs->fs_frag) {
  479                 size = fs->fs_bsize;
  480                 if (i + fs->fs_frag > blks)
  481                         size = (blks - i) * fs->fs_fsize;
  482                 error = bread(devvp, fsbtodb(fs, fs->fs_csaddr + i), size,
  483                     NOCRED, &bp);
  484                 if (error)
  485                         return (error);
  486                 bcopy(bp->b_data, space, (u_int)size);
  487                 space = (char *)space + size;
  488                 brelse(bp);
  489         }
  490         /*
  491          * We no longer know anything about clusters per cylinder group.
  492          */
  493         if (fs->fs_contigsumsize > 0) {
  494                 lp = fs->fs_maxcluster;
  495                 for (i = 0; i < fs->fs_ncg; i++)
  496                         *lp++ = fs->fs_contigsumsize;
  497         }
  498 
  499 loop:
  500         MNT_ILOCK(mp);
  501         for (vp = TAILQ_FIRST(&mp->mnt_nvnodelist); vp != NULL; vp = nvp) {
  502                 if (vp->v_mount != mp) {
  503                         MNT_IUNLOCK(mp);
  504                         goto loop;
  505                 }
  506                 nvp = TAILQ_NEXT(vp, v_nmntvnodes);
  507                 VI_LOCK(vp);
  508                 if (vp->v_iflag & VI_XLOCK) {
  509                         VI_UNLOCK(vp);
  510                         continue;
  511                 }
  512                 MNT_IUNLOCK(mp);
  513                 /*
  514                  * Step 4: invalidate all inactive vnodes.
  515                  */
  516                 if (vp->v_usecount == 0) {
  517                         vgonel(vp, td);
  518                         goto loop;
  519                 }
  520                 /*
  521                  * Step 5: invalidate all cached file data.
  522                  */
  523                 if (vget(vp, LK_EXCLUSIVE | LK_INTERLOCK, td)) {
  524                         goto loop;
  525                 }
  526                 if (vinvalbuf(vp, 0, cred, td, 0, 0))
  527                         panic("ffs_reload: dirty2");
  528                 /*
  529                  * Step 6: re-read inode data for all active vnodes.
  530                  */
  531                 ip = VTOI(vp);
  532                 error =
  533                     bread(devvp, fsbtodb(fs, ino_to_fsba(fs, ip->i_number)),
  534                     (int)fs->fs_bsize, NOCRED, &bp);
  535                 if (error) {
  536                         VOP_UNLOCK(vp, 0, td);
  537                         vrele(vp);
  538                         return (error);
  539                 }
  540                 ffs_load_inode(bp, ip, fs, ip->i_number);
  541                 ip->i_effnlink = ip->i_nlink;
  542                 brelse(bp);
  543                 VOP_UNLOCK(vp, 0, td);
  544                 vrele(vp);
  545                 MNT_ILOCK(mp);
  546         }
  547         MNT_IUNLOCK(mp);
  548         return (0);
  549 }
  550 
  551 /*
  552  * Possible superblock locations ordered from most to least likely.
  553  */
  554 static int sblock_try[] = SBLOCKSEARCH;
  555 
  556 /*
  557  * Common code for mount and mountroot
  558  */
  559 static int
  560 ffs_mountfs(devvp, mp, td)
  561         struct vnode *devvp;
  562         struct mount *mp;
  563         struct thread *td;
  564 {
  565         struct ufsmount *ump;
  566         struct buf *bp;
  567         struct fs *fs;
  568         dev_t dev;
  569         void *space;
  570         ufs2_daddr_t sblockloc;
  571         int error, i, blks, size, ronly;
  572         int32_t *lp;
  573         struct ucred *cred;
  574         size_t strsize;
  575         int ncount;
  576 
  577         dev = devvp->v_rdev;
  578         cred = td ? td->td_ucred : NOCRED;
  579         /*
  580          * Disallow multiple mounts of the same device.
  581          * Disallow mounting of a device that is currently in use
  582          * (except for root, which might share swap device for miniroot).
  583          * Flush out any old buffers remaining from a previous use.
  584          */
  585         error = vfs_mountedon(devvp);
  586         if (error)
  587                 return (error);
  588         ncount = vcount(devvp);
  589 
  590         if (ncount > 1 && devvp != rootvp)
  591                 return (EBUSY);
  592         vn_lock(devvp, LK_EXCLUSIVE | LK_RETRY, td);
  593         error = vinvalbuf(devvp, V_SAVE, cred, td, 0, 0);
  594         VOP_UNLOCK(devvp, 0, td);
  595         if (error)
  596                 return (error);
  597 
  598         /*
  599          * Only VMIO the backing device if the backing device is a real
  600          * block device.
  601          * Note that it is optional that the backing device be VMIOed.  This
  602          * increases the opportunity for metadata caching.
  603          */
  604         if (vn_isdisk(devvp, NULL)) {
  605                 vn_lock(devvp, LK_EXCLUSIVE | LK_RETRY, td);
  606                 vfs_object_create(devvp, td, cred);
  607                 VOP_UNLOCK(devvp, 0, td);
  608         }
  609 
  610         ronly = (mp->mnt_flag & MNT_RDONLY) != 0;
  611         vn_lock(devvp, LK_EXCLUSIVE | LK_RETRY, td);
  612         /*
  613          * XXX: We don't re-VOP_OPEN in FREAD|FWRITE mode if the filesystem
  614          * XXX: is subsequently remounted, so open it FREAD|FWRITE from the
  615          * XXX: start to avoid getting trashed later on.
  616          */
  617 #ifdef notyet
  618         error = VOP_OPEN(devvp, ronly ? FREAD : FREAD|FWRITE, FSCRED, td, -1);
  619 #else
  620         error = VOP_OPEN(devvp, FREAD|FWRITE, FSCRED, td, -1);
  621 #endif
  622         VOP_UNLOCK(devvp, 0, td);
  623         if (error)
  624                 return (error);
  625         if (devvp->v_rdev->si_iosize_max != 0)
  626                 mp->mnt_iosize_max = devvp->v_rdev->si_iosize_max;
  627         if (mp->mnt_iosize_max > MAXPHYS)
  628                 mp->mnt_iosize_max = MAXPHYS;
  629 
  630         bp = NULL;
  631         ump = NULL;
  632         fs = NULL;
  633         sblockloc = 0;
  634         /*
  635          * Try reading the superblock in each of its possible locations.
  636          */
  637         for (i = 0; sblock_try[i] != -1; i++) {
  638                 if ((error = bread(devvp, sblock_try[i] / DEV_BSIZE, SBLOCKSIZE,
  639                     cred, &bp)) != 0)
  640                         goto out;
  641                 fs = (struct fs *)bp->b_data;
  642                 sblockloc = sblock_try[i];
  643                 if ((fs->fs_magic == FS_UFS1_MAGIC ||
  644                      (fs->fs_magic == FS_UFS2_MAGIC &&
  645                       (fs->fs_sblockloc == sblockloc ||
  646                        (fs->fs_old_flags & FS_FLAGS_UPDATED) == 0))) &&
  647                     fs->fs_bsize <= MAXBSIZE &&
  648                     fs->fs_bsize >= sizeof(struct fs))
  649                         break;
  650                 brelse(bp);
  651                 bp = NULL;
  652         }
  653         if (sblock_try[i] == -1) {
  654                 error = EINVAL;         /* XXX needs translation */
  655                 goto out;
  656         }
  657         fs->fs_fmod = 0;
  658         fs->fs_flags &= ~FS_INDEXDIRS;  /* no support for directory indicies */
  659         fs->fs_flags &= ~FS_UNCLEAN;
  660         if (fs->fs_clean == 0) {
  661                 fs->fs_flags |= FS_UNCLEAN;
  662                 if (ronly || (mp->mnt_flag & MNT_FORCE) ||
  663                     ((fs->fs_flags & FS_NEEDSFSCK) == 0 &&
  664                      (fs->fs_flags & FS_DOSOFTDEP))) {
  665                         printf(
  666 "WARNING: %s was not properly dismounted\n",
  667                             fs->fs_fsmnt);
  668                 } else {
  669                         printf(
  670 "WARNING: R/W mount of %s denied.  Filesystem is not clean - run fsck\n",
  671                             fs->fs_fsmnt);
  672                         error = EPERM;
  673                         goto out;
  674                 }
  675                 if ((fs->fs_pendingblocks != 0 || fs->fs_pendinginodes != 0) &&
  676                     (mp->mnt_flag & MNT_FORCE)) {
  677                         printf("%s: lost blocks %jd files %d\n", fs->fs_fsmnt,
  678                             (intmax_t)fs->fs_pendingblocks,
  679                             fs->fs_pendinginodes);
  680                         fs->fs_pendingblocks = 0;
  681                         fs->fs_pendinginodes = 0;
  682                 }
  683         }
  684         if (fs->fs_pendingblocks != 0 || fs->fs_pendinginodes != 0) {
  685                 printf("%s: mount pending error: blocks %jd files %d\n",
  686                     fs->fs_fsmnt, (intmax_t)fs->fs_pendingblocks,
  687                     fs->fs_pendinginodes);
  688                 fs->fs_pendingblocks = 0;
  689                 fs->fs_pendinginodes = 0;
  690         }
  691         ump = malloc(sizeof *ump, M_UFSMNT, M_WAITOK | M_ZERO);
  692         ump->um_fs = malloc((u_long)fs->fs_sbsize, M_UFSMNT,
  693             M_WAITOK);
  694         if (fs->fs_magic == FS_UFS1_MAGIC) {
  695                 ump->um_fstype = UFS1;
  696                 ump->um_balloc = ffs_balloc_ufs1;
  697         } else {
  698                 ump->um_fstype = UFS2;
  699                 ump->um_balloc = ffs_balloc_ufs2;
  700         }
  701         ump->um_blkatoff = ffs_blkatoff;
  702         ump->um_truncate = ffs_truncate;
  703         ump->um_update = ffs_update;
  704         ump->um_valloc = ffs_valloc;
  705         ump->um_vfree = ffs_vfree;
  706         ump->um_ifree = ffs_ifree;
  707         bcopy(bp->b_data, ump->um_fs, (u_int)fs->fs_sbsize);
  708         if (fs->fs_sbsize < SBLOCKSIZE)
  709                 bp->b_flags |= B_INVAL | B_NOCACHE;
  710         brelse(bp);
  711         bp = NULL;
  712         fs = ump->um_fs;
  713         ffs_oldfscompat_read(fs, ump, sblockloc);
  714         fs->fs_ronly = ronly;
  715         size = fs->fs_cssize;
  716         blks = howmany(size, fs->fs_fsize);
  717         if (fs->fs_contigsumsize > 0)
  718                 size += fs->fs_ncg * sizeof(int32_t);
  719         size += fs->fs_ncg * sizeof(u_int8_t);
  720         space = malloc((u_long)size, M_UFSMNT, M_WAITOK);
  721         fs->fs_csp = space;
  722         for (i = 0; i < blks; i += fs->fs_frag) {
  723                 size = fs->fs_bsize;
  724                 if (i + fs->fs_frag > blks)
  725                         size = (blks - i) * fs->fs_fsize;
  726                 if ((error = bread(devvp, fsbtodb(fs, fs->fs_csaddr + i), size,
  727                     cred, &bp)) != 0) {
  728                         free(fs->fs_csp, M_UFSMNT);
  729                         goto out;
  730                 }
  731                 bcopy(bp->b_data, space, (u_int)size);
  732                 space = (char *)space + size;
  733                 brelse(bp);
  734                 bp = NULL;
  735         }
  736         if (fs->fs_contigsumsize > 0) {
  737                 fs->fs_maxcluster = lp = space;
  738                 for (i = 0; i < fs->fs_ncg; i++)
  739                         *lp++ = fs->fs_contigsumsize;
  740                 space = lp;
  741         }
  742         size = fs->fs_ncg * sizeof(u_int8_t);
  743         fs->fs_contigdirs = (u_int8_t *)space;
  744         bzero(fs->fs_contigdirs, size);
  745         fs->fs_active = NULL;
  746         mp->mnt_data = (qaddr_t)ump;
  747         mp->mnt_stat.f_fsid.val[0] = fs->fs_id[0];
  748         mp->mnt_stat.f_fsid.val[1] = fs->fs_id[1];
  749         if (fs->fs_id[0] == 0 || fs->fs_id[1] == 0 || 
  750             vfs_getvfs(&mp->mnt_stat.f_fsid)) 
  751                 vfs_getnewfsid(mp);
  752         mp->mnt_maxsymlinklen = fs->fs_maxsymlinklen;
  753         mp->mnt_flag |= MNT_LOCAL;
  754         if ((fs->fs_flags & FS_MULTILABEL) != 0)
  755 #ifdef MAC
  756                 mp->mnt_flag |= MNT_MULTILABEL;
  757 #else
  758                 printf(
  759 "WARNING: %s: multilabel flag on fs but no MAC support\n",
  760                     fs->fs_fsmnt);
  761 #endif
  762         if ((fs->fs_flags & FS_ACLS) != 0)
  763 #ifdef UFS_ACL
  764                 mp->mnt_flag |= MNT_ACLS;
  765 #else
  766                 printf(
  767 "WARNING: %s: ACLs flag on fs but no ACLs support\n",
  768                     fs->fs_fsmnt);
  769 #endif
  770         ump->um_mountp = mp;
  771         ump->um_dev = dev;
  772         ump->um_devvp = devvp;
  773         ump->um_nindir = fs->fs_nindir;
  774         ump->um_bptrtodb = fs->fs_fsbtodb;
  775         ump->um_seqinc = fs->fs_frag;
  776         for (i = 0; i < MAXQUOTAS; i++)
  777                 ump->um_quotas[i] = NULLVP;
  778 #ifdef UFS_EXTATTR
  779         ufs_extattr_uepm_init(&ump->um_extattr);
  780 #endif
  781         devvp->v_rdev->si_mountpoint = mp;
  782 
  783         /*
  784          * Set FS local "last mounted on" information (NULL pad)
  785          */
  786         copystr(        mp->mnt_stat.f_mntonname,       /* mount point*/
  787                         fs->fs_fsmnt,                   /* copy area*/
  788                         sizeof(fs->fs_fsmnt) - 1,       /* max size*/
  789                         &strsize);                      /* real size*/
  790         bzero( fs->fs_fsmnt + strsize, sizeof(fs->fs_fsmnt) - strsize);
  791 
  792         if( mp->mnt_flag & MNT_ROOTFS) {
  793                 /*
  794                  * Root mount; update timestamp in mount structure.
  795                  * this will be used by the common root mount code
  796                  * to update the system clock.
  797                  */
  798                 mp->mnt_time = fs->fs_time;
  799         }
  800 
  801         if (ronly == 0) {
  802                 if ((fs->fs_flags & FS_DOSOFTDEP) &&
  803                     (error = softdep_mount(devvp, mp, fs, cred)) != 0) {
  804                         free(fs->fs_csp, M_UFSMNT);
  805                         goto out;
  806                 }
  807                 if (fs->fs_snapinum[0] != 0)
  808                         ffs_snapshot_mount(mp);
  809                 fs->fs_fmod = 1;
  810                 fs->fs_clean = 0;
  811                 (void) ffs_sbupdate(ump, MNT_WAIT);
  812         }
  813 #ifdef UFS_EXTATTR
  814 #ifdef UFS_EXTATTR_AUTOSTART
  815         /*
  816          *
  817          * Auto-starting does the following:
  818          *      - check for /.attribute in the fs, and extattr_start if so
  819          *      - for each file in .attribute, enable that file with
  820          *        an attribute of the same name.
  821          * Not clear how to report errors -- probably eat them.
  822          * This would all happen while the filesystem was busy/not
  823          * available, so would effectively be "atomic".
  824          */
  825         (void) ufs_extattr_autostart(mp, td);
  826 #endif /* !UFS_EXTATTR_AUTOSTART */
  827 #endif /* !UFS_EXTATTR */
  828         return (0);
  829 out:
  830         devvp->v_rdev->si_mountpoint = NULL;
  831         if (bp)
  832                 brelse(bp);
  833         /* XXX: see comment above VOP_OPEN */
  834 #ifdef notyet
  835         (void)VOP_CLOSE(devvp, ronly ? FREAD : FREAD|FWRITE, cred, td);
  836 #else
  837         (void)VOP_CLOSE(devvp, FREAD|FWRITE, cred, td);
  838 #endif
  839         if (ump) {
  840                 free(ump->um_fs, M_UFSMNT);
  841                 free(ump, M_UFSMNT);
  842                 mp->mnt_data = (qaddr_t)0;
  843         }
  844         return (error);
  845 }
  846 
  847 #include <sys/sysctl.h>
  848 int bigcgs = 0;
  849 SYSCTL_INT(_debug, OID_AUTO, bigcgs, CTLFLAG_RW, &bigcgs, 0, "");
  850 
  851 /*
  852  * Sanity checks for loading old filesystem superblocks.
  853  * See ffs_oldfscompat_write below for unwound actions.
  854  *
  855  * XXX - Parts get retired eventually.
  856  * Unfortunately new bits get added.
  857  */
  858 static void
  859 ffs_oldfscompat_read(fs, ump, sblockloc)
  860         struct fs *fs;
  861         struct ufsmount *ump;
  862         ufs2_daddr_t sblockloc;
  863 {
  864         off_t maxfilesize;
  865 
  866         /*
  867          * If not yet done, update fs_flags location and value of fs_sblockloc.
  868          */
  869         if ((fs->fs_old_flags & FS_FLAGS_UPDATED) == 0) {
  870                 fs->fs_flags = fs->fs_old_flags;
  871                 fs->fs_old_flags |= FS_FLAGS_UPDATED;
  872                 fs->fs_sblockloc = sblockloc;
  873         }
  874         /*
  875          * If not yet done, update UFS1 superblock with new wider fields.
  876          */
  877         if (fs->fs_magic == FS_UFS1_MAGIC && fs->fs_maxbsize != fs->fs_bsize) {
  878                 fs->fs_maxbsize = fs->fs_bsize;
  879                 fs->fs_time = fs->fs_old_time;
  880                 fs->fs_size = fs->fs_old_size;
  881                 fs->fs_dsize = fs->fs_old_dsize;
  882                 fs->fs_csaddr = fs->fs_old_csaddr;
  883                 fs->fs_cstotal.cs_ndir = fs->fs_old_cstotal.cs_ndir;
  884                 fs->fs_cstotal.cs_nbfree = fs->fs_old_cstotal.cs_nbfree;
  885                 fs->fs_cstotal.cs_nifree = fs->fs_old_cstotal.cs_nifree;
  886                 fs->fs_cstotal.cs_nffree = fs->fs_old_cstotal.cs_nffree;
  887         }
  888         if (fs->fs_magic == FS_UFS1_MAGIC &&
  889             fs->fs_old_inodefmt < FS_44INODEFMT) {
  890                 fs->fs_maxfilesize = (u_quad_t) 1LL << 39;
  891                 fs->fs_qbmask = ~fs->fs_bmask;
  892                 fs->fs_qfmask = ~fs->fs_fmask;
  893         }
  894         if (fs->fs_magic == FS_UFS1_MAGIC) {
  895                 ump->um_savedmaxfilesize = fs->fs_maxfilesize;
  896                 maxfilesize = (u_int64_t)0x40000000 * fs->fs_bsize - 1;
  897                 if (fs->fs_maxfilesize > maxfilesize)
  898                         fs->fs_maxfilesize = maxfilesize;
  899         }
  900         /* Compatibility for old filesystems */
  901         if (fs->fs_avgfilesize <= 0)
  902                 fs->fs_avgfilesize = AVFILESIZ;
  903         if (fs->fs_avgfpdir <= 0)
  904                 fs->fs_avgfpdir = AFPDIR;
  905         if (bigcgs) {
  906                 fs->fs_save_cgsize = fs->fs_cgsize;
  907                 fs->fs_cgsize = fs->fs_bsize;
  908         }
  909 }
  910 
  911 /*
  912  * Unwinding superblock updates for old filesystems.
  913  * See ffs_oldfscompat_read above for details.
  914  *
  915  * XXX - Parts get retired eventually.
  916  * Unfortunately new bits get added.
  917  */
  918 static void
  919 ffs_oldfscompat_write(fs, ump)
  920         struct fs *fs;
  921         struct ufsmount *ump;
  922 {
  923 
  924         /*
  925          * Copy back UFS2 updated fields that UFS1 inspects.
  926          */
  927         if (fs->fs_magic == FS_UFS1_MAGIC) {
  928                 fs->fs_old_time = fs->fs_time;
  929                 fs->fs_old_cstotal.cs_ndir = fs->fs_cstotal.cs_ndir;
  930                 fs->fs_old_cstotal.cs_nbfree = fs->fs_cstotal.cs_nbfree;
  931                 fs->fs_old_cstotal.cs_nifree = fs->fs_cstotal.cs_nifree;
  932                 fs->fs_old_cstotal.cs_nffree = fs->fs_cstotal.cs_nffree;
  933                 fs->fs_maxfilesize = ump->um_savedmaxfilesize;
  934         }
  935         if (bigcgs) {
  936                 fs->fs_cgsize = fs->fs_save_cgsize;
  937                 fs->fs_save_cgsize = 0;
  938         }
  939 }
  940 
  941 /*
  942  * unmount system call
  943  */
  944 int
  945 ffs_unmount(mp, mntflags, td)
  946         struct mount *mp;
  947         int mntflags;
  948         struct thread *td;
  949 {
  950         struct ufsmount *ump = VFSTOUFS(mp);
  951         struct fs *fs;
  952         int error, flags;
  953 
  954         flags = 0;
  955         if (mntflags & MNT_FORCE) {
  956                 flags |= FORCECLOSE;
  957         }
  958 #ifdef UFS_EXTATTR
  959         if ((error = ufs_extattr_stop(mp, td))) {
  960                 if (error != EOPNOTSUPP)
  961                         printf("ffs_unmount: ufs_extattr_stop returned %d\n",
  962                             error);
  963         } else {
  964                 ufs_extattr_uepm_destroy(&ump->um_extattr);
  965         }
  966 #endif
  967         if (mp->mnt_flag & MNT_SOFTDEP) {
  968                 if ((error = softdep_flushfiles(mp, flags, td)) != 0)
  969                         return (error);
  970         } else {
  971                 if ((error = ffs_flushfiles(mp, flags, td)) != 0)
  972                         return (error);
  973         }
  974         fs = ump->um_fs;
  975         if (fs->fs_pendingblocks != 0 || fs->fs_pendinginodes != 0) {
  976                 printf("%s: unmount pending error: blocks %jd files %d\n",
  977                     fs->fs_fsmnt, (intmax_t)fs->fs_pendingblocks,
  978                     fs->fs_pendinginodes);
  979                 fs->fs_pendingblocks = 0;
  980                 fs->fs_pendinginodes = 0;
  981         }
  982         if (fs->fs_ronly == 0) {
  983                 fs->fs_clean = fs->fs_flags & (FS_UNCLEAN|FS_NEEDSFSCK) ? 0 : 1;
  984                 error = ffs_sbupdate(ump, MNT_WAIT);
  985                 if (error) {
  986                         fs->fs_clean = 0;
  987                         return (error);
  988                 }
  989         }
  990         ump->um_devvp->v_rdev->si_mountpoint = NULL;
  991 
  992         vinvalbuf(ump->um_devvp, V_SAVE, NOCRED, td, 0, 0);
  993         /* XXX: see comment above VOP_OPEN */
  994 #ifdef notyet
  995         error = VOP_CLOSE(ump->um_devvp, fs->fs_ronly ? FREAD : FREAD|FWRITE,
  996                 NOCRED, td);
  997 #else
  998         error = VOP_CLOSE(ump->um_devvp, FREAD|FWRITE, NOCRED, td);
  999 #endif
 1000 
 1001         vrele(ump->um_devvp);
 1002 
 1003         free(fs->fs_csp, M_UFSMNT);
 1004         free(fs, M_UFSMNT);
 1005         free(ump, M_UFSMNT);
 1006         mp->mnt_data = (qaddr_t)0;
 1007         mp->mnt_flag &= ~MNT_LOCAL;
 1008         return (error);
 1009 }
 1010 
 1011 /*
 1012  * Flush out all the files in a filesystem.
 1013  */
 1014 int
 1015 ffs_flushfiles(mp, flags, td)
 1016         struct mount *mp;
 1017         int flags;
 1018         struct thread *td;
 1019 {
 1020         struct ufsmount *ump;
 1021         int error;
 1022 
 1023         ump = VFSTOUFS(mp);
 1024 #ifdef QUOTA
 1025         if (mp->mnt_flag & MNT_QUOTA) {
 1026                 int i;
 1027                 error = vflush(mp, 0, SKIPSYSTEM|flags);
 1028                 if (error)
 1029                         return (error);
 1030                 for (i = 0; i < MAXQUOTAS; i++) {
 1031                         if (ump->um_quotas[i] == NULLVP)
 1032                                 continue;
 1033                         quotaoff(td, mp, i);
 1034                 }
 1035                 /*
 1036                  * Here we fall through to vflush again to ensure
 1037                  * that we have gotten rid of all the system vnodes.
 1038                  */
 1039         }
 1040 #endif
 1041         ASSERT_VOP_LOCKED(ump->um_devvp, "ffs_flushfiles");
 1042         if (ump->um_devvp->v_vflag & VV_COPYONWRITE) {
 1043                 if ((error = vflush(mp, 0, SKIPSYSTEM | flags)) != 0)
 1044                         return (error);
 1045                 ffs_snapshot_unmount(mp);
 1046                 /*
 1047                  * Here we fall through to vflush again to ensure
 1048                  * that we have gotten rid of all the system vnodes.
 1049                  */
 1050         }
 1051         /*
 1052          * Flush all the files.
 1053          */
 1054         if ((error = vflush(mp, 0, flags)) != 0)
 1055                 return (error);
 1056         /*
 1057          * Flush filesystem metadata.
 1058          */
 1059         vn_lock(ump->um_devvp, LK_EXCLUSIVE | LK_RETRY, td);
 1060         error = VOP_FSYNC(ump->um_devvp, td->td_ucred, MNT_WAIT, td);
 1061         VOP_UNLOCK(ump->um_devvp, 0, td);
 1062         return (error);
 1063 }
 1064 
 1065 /*
 1066  * Get filesystem statistics.
 1067  */
 1068 int
 1069 ffs_statfs(mp, sbp, td)
 1070         struct mount *mp;
 1071         struct statfs *sbp;
 1072         struct thread *td;
 1073 {
 1074         struct ufsmount *ump;
 1075         struct fs *fs;
 1076 
 1077         ump = VFSTOUFS(mp);
 1078         fs = ump->um_fs;
 1079         if (fs->fs_magic != FS_UFS1_MAGIC && fs->fs_magic != FS_UFS2_MAGIC)
 1080                 panic("ffs_statfs");
 1081         sbp->f_version = STATFS_VERSION;
 1082         sbp->f_bsize = fs->fs_fsize;
 1083         sbp->f_iosize = fs->fs_bsize;
 1084         sbp->f_blocks = fs->fs_dsize;
 1085         sbp->f_bfree = fs->fs_cstotal.cs_nbfree * fs->fs_frag +
 1086             fs->fs_cstotal.cs_nffree + dbtofsb(fs, fs->fs_pendingblocks);
 1087         sbp->f_bavail = freespace(fs, fs->fs_minfree) +
 1088             dbtofsb(fs, fs->fs_pendingblocks);
 1089         sbp->f_files =  fs->fs_ncg * fs->fs_ipg - ROOTINO;
 1090         sbp->f_ffree = fs->fs_cstotal.cs_nifree + fs->fs_pendinginodes;
 1091         sbp->f_namemax = NAME_MAX;
 1092         if (sbp != &mp->mnt_stat) {
 1093                 sbp->f_flags = mp->mnt_flag & MNT_VISFLAGMASK;
 1094                 sbp->f_type = mp->mnt_vfc->vfc_typenum;
 1095                 sbp->f_syncwrites = mp->mnt_stat.f_syncwrites;
 1096                 sbp->f_asyncwrites = mp->mnt_stat.f_asyncwrites;
 1097                 sbp->f_syncreads = mp->mnt_stat.f_syncreads;
 1098                 sbp->f_asyncreads = mp->mnt_stat.f_asyncreads;
 1099                 sbp->f_owner = mp->mnt_stat.f_owner;
 1100                 sbp->f_fsid = mp->mnt_stat.f_fsid;
 1101                 bcopy((caddr_t)mp->mnt_stat.f_fstypename,
 1102                         (caddr_t)&sbp->f_fstypename[0], MFSNAMELEN);
 1103                 bcopy((caddr_t)mp->mnt_stat.f_mntonname,
 1104                         (caddr_t)&sbp->f_mntonname[0], MNAMELEN);
 1105                 bcopy((caddr_t)mp->mnt_stat.f_mntfromname,
 1106                         (caddr_t)&sbp->f_mntfromname[0], MNAMELEN);
 1107         }
 1108         return (0);
 1109 }
 1110 
 1111 /*
 1112  * Go through the disk queues to initiate sandbagged IO;
 1113  * go through the inodes to write those that have been modified;
 1114  * initiate the writing of the super block if it has been modified.
 1115  *
 1116  * Note: we are always called with the filesystem marked `MPBUSY'.
 1117  */
 1118 int
 1119 ffs_sync(mp, waitfor, cred, td)
 1120         struct mount *mp;
 1121         int waitfor;
 1122         struct ucred *cred;
 1123         struct thread *td;
 1124 {
 1125         struct vnode *nvp, *vp, *devvp;
 1126         struct inode *ip;
 1127         struct ufsmount *ump = VFSTOUFS(mp);
 1128         struct fs *fs;
 1129         int error, count, wait, lockreq, allerror = 0;
 1130 
 1131         fs = ump->um_fs;
 1132         if (fs->fs_fmod != 0 && fs->fs_ronly != 0) {            /* XXX */
 1133                 printf("fs = %s\n", fs->fs_fsmnt);
 1134                 panic("ffs_sync: rofs mod");
 1135         }
 1136         /*
 1137          * Write back each (modified) inode.
 1138          */
 1139         wait = 0;
 1140         lockreq = LK_EXCLUSIVE | LK_NOWAIT;
 1141         if (waitfor == MNT_WAIT) {
 1142                 wait = 1;
 1143                 lockreq = LK_EXCLUSIVE;
 1144         }
 1145         lockreq |= LK_INTERLOCK;
 1146         MNT_ILOCK(mp);
 1147 loop:
 1148         for (vp = TAILQ_FIRST(&mp->mnt_nvnodelist); vp != NULL; vp = nvp) {
 1149                 /*
 1150                  * If the vnode that we are about to sync is no longer
 1151                  * associated with this mount point, start over.
 1152                  */
 1153                 if (vp->v_mount != mp)
 1154                         goto loop;
 1155 
 1156                 /*
 1157                  * Depend on the mntvnode_slock to keep things stable enough
 1158                  * for a quick test.  Since there might be hundreds of
 1159                  * thousands of vnodes, we cannot afford even a subroutine
 1160                  * call unless there's a good chance that we have work to do.
 1161                  */
 1162                 nvp = TAILQ_NEXT(vp, v_nmntvnodes);
 1163                 VI_LOCK(vp);
 1164                 if (vp->v_iflag & VI_XLOCK) {
 1165                         VI_UNLOCK(vp);
 1166                         continue;
 1167                 }
 1168                 ip = VTOI(vp);
 1169                 if (vp->v_type == VNON || ((ip->i_flag &
 1170                     (IN_ACCESS | IN_CHANGE | IN_MODIFIED | IN_UPDATE)) == 0 &&
 1171                     TAILQ_EMPTY(&vp->v_dirtyblkhd))) {
 1172                         VI_UNLOCK(vp);
 1173                         continue;
 1174                 }
 1175                 MNT_IUNLOCK(mp);
 1176                 if ((error = vget(vp, lockreq, td)) != 0) {
 1177                         MNT_ILOCK(mp);
 1178                         if (error == ENOENT)
 1179                                 goto loop;
 1180                         continue;
 1181                 }
 1182                 if ((error = VOP_FSYNC(vp, cred, waitfor, td)) != 0)
 1183                         allerror = error;
 1184                 VOP_UNLOCK(vp, 0, td);
 1185                 vrele(vp);
 1186                 MNT_ILOCK(mp);
 1187                 if (TAILQ_NEXT(vp, v_nmntvnodes) != nvp)
 1188                         goto loop;
 1189         }
 1190         MNT_IUNLOCK(mp);
 1191         /*
 1192          * Force stale filesystem control information to be flushed.
 1193          */
 1194         if (waitfor == MNT_WAIT) {
 1195                 if ((error = softdep_flushworklist(ump->um_mountp, &count, td)))
 1196                         allerror = error;
 1197                 /* Flushed work items may create new vnodes to clean */
 1198                 if (allerror == 0 && count) {
 1199                         MNT_ILOCK(mp);
 1200                         goto loop;
 1201                 }
 1202         }
 1203 #ifdef QUOTA
 1204         qsync(mp);
 1205 #endif
 1206         devvp = ump->um_devvp;
 1207         VI_LOCK(devvp);
 1208         if (waitfor != MNT_LAZY &&
 1209             (devvp->v_numoutput > 0 || TAILQ_FIRST(&devvp->v_dirtyblkhd))) {
 1210                 vn_lock(devvp, LK_EXCLUSIVE | LK_RETRY | LK_INTERLOCK, td);
 1211                 if ((error = VOP_FSYNC(devvp, cred, waitfor, td)) != 0)
 1212                         allerror = error;
 1213                 VOP_UNLOCK(devvp, 0, td);
 1214                 if (allerror == 0 && waitfor == MNT_WAIT) {
 1215                         MNT_ILOCK(mp);
 1216                         goto loop;
 1217                 }
 1218         } else
 1219                 VI_UNLOCK(devvp);
 1220         /*
 1221          * Write back modified superblock.
 1222          */
 1223         if (fs->fs_fmod != 0 && (error = ffs_sbupdate(ump, waitfor)) != 0)
 1224                 allerror = error;
 1225         return (allerror);
 1226 }
 1227 
 1228 int
 1229 ffs_vget(mp, ino, flags, vpp)
 1230         struct mount *mp;
 1231         ino_t ino;
 1232         int flags;
 1233         struct vnode **vpp;
 1234 {
 1235         struct thread *td = curthread;          /* XXX */
 1236         struct fs *fs;
 1237         struct inode *ip;
 1238         struct ufsmount *ump;
 1239         struct buf *bp;
 1240         struct vnode *vp;
 1241         dev_t dev;
 1242         int error;
 1243 
 1244         ump = VFSTOUFS(mp);
 1245         dev = ump->um_dev;
 1246 
 1247         /*
 1248          * We do not lock vnode creation as it is believed to be too
 1249          * expensive for such rare case as simultaneous creation of vnode
 1250          * for same ino by different processes. We just allow them to race
 1251          * and check later to decide who wins. Let the race begin!
 1252          */
 1253         if ((error = ufs_ihashget(dev, ino, flags, vpp)) != 0)
 1254                 return (error);
 1255         if (*vpp != NULL)
 1256                 return (0);
 1257 
 1258         /*
 1259          * If this MALLOC() is performed after the getnewvnode()
 1260          * it might block, leaving a vnode with a NULL v_data to be
 1261          * found by ffs_sync() if a sync happens to fire right then,
 1262          * which will cause a panic because ffs_sync() blindly
 1263          * dereferences vp->v_data (as well it should).
 1264          */
 1265         ip = uma_zalloc(uma_inode, M_WAITOK);
 1266 
 1267         /* Allocate a new vnode/inode. */
 1268         error = getnewvnode("ufs", mp, ffs_vnodeop_p, &vp);
 1269         if (error) {
 1270                 *vpp = NULL;
 1271                 uma_zfree(uma_inode, ip);
 1272                 return (error);
 1273         }
 1274         bzero((caddr_t)ip, sizeof(struct inode));
 1275         /*
 1276          * FFS supports recursive locking.
 1277          */
 1278         vp->v_vnlock->lk_flags |= LK_CANRECURSE;
 1279         vp->v_data = ip;
 1280         ip->i_vnode = vp;
 1281         ip->i_ump = ump;
 1282         ip->i_fs = fs = ump->um_fs;
 1283         ip->i_dev = dev;
 1284         ip->i_number = ino;
 1285 #ifdef QUOTA
 1286         {
 1287                 int i;
 1288                 for (i = 0; i < MAXQUOTAS; i++)
 1289                         ip->i_dquot[i] = NODQUOT;
 1290         }
 1291 #endif
 1292         /*
 1293          * Exclusively lock the vnode before adding to hash. Note, that we
 1294          * must not release nor downgrade the lock (despite flags argument
 1295          * says) till it is fully initialized.
 1296          */
 1297         lockmgr(vp->v_vnlock, LK_EXCLUSIVE, (struct mtx *)0, td);
 1298 
 1299         /*
 1300          * Atomicaly (in terms of ufs_hash operations) check the hash for
 1301          * duplicate of vnode being created and add it to the hash. If a
 1302          * duplicate vnode was found, it will be vget()ed from hash for us.
 1303          */
 1304         if ((error = ufs_ihashins(ip, flags, vpp)) != 0) {
 1305                 vput(vp);
 1306                 *vpp = NULL;
 1307                 return (error);
 1308         }
 1309 
 1310         /* We lost the race, then throw away our vnode and return existing */
 1311         if (*vpp != NULL) {
 1312                 vput(vp);
 1313                 return (0);
 1314         }
 1315 
 1316         /* Read in the disk contents for the inode, copy into the inode. */
 1317         error = bread(ump->um_devvp, fsbtodb(fs, ino_to_fsba(fs, ino)),
 1318             (int)fs->fs_bsize, NOCRED, &bp);
 1319         if (error) {
 1320                 /*
 1321                  * The inode does not contain anything useful, so it would
 1322                  * be misleading to leave it on its hash chain. With mode
 1323                  * still zero, it will be unlinked and returned to the free
 1324                  * list by vput().
 1325                  */
 1326                 brelse(bp);
 1327                 vput(vp);
 1328                 *vpp = NULL;
 1329                 return (error);
 1330         }
 1331         if (ip->i_ump->um_fstype == UFS1)
 1332                 ip->i_din1 = uma_zalloc(uma_ufs1, M_WAITOK);
 1333         else
 1334                 ip->i_din2 = uma_zalloc(uma_ufs2, M_WAITOK);
 1335         ffs_load_inode(bp, ip, fs, ino);
 1336         if (DOINGSOFTDEP(vp))
 1337                 softdep_load_inodeblock(ip);
 1338         else
 1339                 ip->i_effnlink = ip->i_nlink;
 1340         bqrelse(bp);
 1341 
 1342         /*
 1343          * Initialize the vnode from the inode, check for aliases.
 1344          * Note that the underlying vnode may have changed.
 1345          */
 1346         error = ufs_vinit(mp, ffs_specop_p, ffs_fifoop_p, &vp);
 1347         if (error) {
 1348                 vput(vp);
 1349                 *vpp = NULL;
 1350                 return (error);
 1351         }
 1352         /*
 1353          * Finish inode initialization.
 1354          */
 1355         VREF(ip->i_devvp);
 1356         /*
 1357          * Set up a generation number for this inode if it does not
 1358          * already have one. This should only happen on old filesystems.
 1359          */
 1360         if (ip->i_gen == 0) {
 1361                 ip->i_gen = arc4random() / 2 + 1;
 1362                 if ((vp->v_mount->mnt_flag & MNT_RDONLY) == 0) {
 1363                         ip->i_flag |= IN_MODIFIED;
 1364                         DIP(ip, i_gen) = ip->i_gen;
 1365                 }
 1366         }
 1367         /*
 1368          * Ensure that uid and gid are correct. This is a temporary
 1369          * fix until fsck has been changed to do the update.
 1370          */
 1371         if (fs->fs_magic == FS_UFS1_MAGIC &&            /* XXX */
 1372             fs->fs_old_inodefmt < FS_44INODEFMT) {      /* XXX */
 1373                 ip->i_uid = ip->i_din1->di_ouid;        /* XXX */
 1374                 ip->i_gid = ip->i_din1->di_ogid;        /* XXX */
 1375         }                                               /* XXX */
 1376 
 1377 #ifdef MAC
 1378         if ((mp->mnt_flag & MNT_MULTILABEL) && ip->i_mode) {
 1379                 /*
 1380                  * If this vnode is already allocated, and we're running
 1381                  * multi-label, attempt to perform a label association
 1382                  * from the extended attributes on the inode.
 1383                  */
 1384                 error = mac_associate_vnode_extattr(mp, vp);
 1385                 if (error) {
 1386                         /* ufs_inactive will release ip->i_devvp ref. */
 1387                         vput(vp);
 1388                         *vpp = NULL;
 1389                         return (error);
 1390                 }
 1391         }
 1392 #endif
 1393 
 1394         *vpp = vp;
 1395         return (0);
 1396 }
 1397 
 1398 /*
 1399  * File handle to vnode
 1400  *
 1401  * Have to be really careful about stale file handles:
 1402  * - check that the inode number is valid
 1403  * - call ffs_vget() to get the locked inode
 1404  * - check for an unallocated inode (i_mode == 0)
 1405  * - check that the given client host has export rights and return
 1406  *   those rights via. exflagsp and credanonp
 1407  */
 1408 int
 1409 ffs_fhtovp(mp, fhp, vpp)
 1410         struct mount *mp;
 1411         struct fid *fhp;
 1412         struct vnode **vpp;
 1413 {
 1414         struct ufid *ufhp;
 1415         struct fs *fs;
 1416 
 1417         ufhp = (struct ufid *)fhp;
 1418         fs = VFSTOUFS(mp)->um_fs;
 1419         if (ufhp->ufid_ino < ROOTINO ||
 1420             ufhp->ufid_ino >= fs->fs_ncg * fs->fs_ipg)
 1421                 return (ESTALE);
 1422         return (ufs_fhtovp(mp, ufhp, vpp));
 1423 }
 1424 
 1425 /*
 1426  * Vnode pointer to File handle
 1427  */
 1428 /* ARGSUSED */
 1429 int
 1430 ffs_vptofh(vp, fhp)
 1431         struct vnode *vp;
 1432         struct fid *fhp;
 1433 {
 1434         struct inode *ip;
 1435         struct ufid *ufhp;
 1436 
 1437         ip = VTOI(vp);
 1438         ufhp = (struct ufid *)fhp;
 1439         ufhp->ufid_len = sizeof(struct ufid);
 1440         ufhp->ufid_ino = ip->i_number;
 1441         ufhp->ufid_gen = ip->i_gen;
 1442         return (0);
 1443 }
 1444 
 1445 /*
 1446  * Initialize the filesystem.
 1447  */
 1448 static int
 1449 ffs_init(vfsp)
 1450         struct vfsconf *vfsp;
 1451 {
 1452 
 1453         softdep_initialize();
 1454         return (ufs_init(vfsp));
 1455 }
 1456 
 1457 /*
 1458  * Undo the work of ffs_init().
 1459  */
 1460 static int
 1461 ffs_uninit(vfsp)
 1462         struct vfsconf *vfsp;
 1463 {
 1464         int ret;
 1465 
 1466         ret = ufs_uninit(vfsp);
 1467         softdep_uninitialize();
 1468         return (ret);
 1469 }
 1470 
 1471 /*
 1472  * Write a superblock and associated information back to disk.
 1473  */
 1474 static int
 1475 ffs_sbupdate(mp, waitfor)
 1476         struct ufsmount *mp;
 1477         int waitfor;
 1478 {
 1479         struct fs *fs = mp->um_fs;
 1480         struct buf *bp;
 1481         int blks;
 1482         void *space;
 1483         int i, size, error, allerror = 0;
 1484 
 1485         if (fs->fs_ronly == 1 &&
 1486             (mp->um_mountp->mnt_flag & (MNT_RDONLY | MNT_UPDATE)) != 
 1487             (MNT_RDONLY | MNT_UPDATE))
 1488                 panic("ffs_sbupdate: write read-only filesystem");
 1489         /*
 1490          * First write back the summary information.
 1491          */
 1492         blks = howmany(fs->fs_cssize, fs->fs_fsize);
 1493         space = fs->fs_csp;
 1494         for (i = 0; i < blks; i += fs->fs_frag) {
 1495                 size = fs->fs_bsize;
 1496                 if (i + fs->fs_frag > blks)
 1497                         size = (blks - i) * fs->fs_fsize;
 1498                 bp = getblk(mp->um_devvp, fsbtodb(fs, fs->fs_csaddr + i),
 1499                     size, 0, 0, 0);
 1500                 bcopy(space, bp->b_data, (u_int)size);
 1501                 space = (char *)space + size;
 1502                 if (waitfor != MNT_WAIT)
 1503                         bawrite(bp);
 1504                 else if ((error = bwrite(bp)) != 0)
 1505                         allerror = error;
 1506         }
 1507         /*
 1508          * Now write back the superblock itself. If any errors occurred
 1509          * up to this point, then fail so that the superblock avoids
 1510          * being written out as clean.
 1511          */
 1512         if (allerror)
 1513                 return (allerror);
 1514         if (fs->fs_magic == FS_UFS1_MAGIC && fs->fs_sblockloc != SBLOCK_UFS1 &&
 1515             (fs->fs_flags & FS_FLAGS_UPDATED) == 0) {
 1516                 printf("%s: correcting fs_sblockloc from %jd to %d\n",
 1517                     fs->fs_fsmnt, fs->fs_sblockloc, SBLOCK_UFS1);
 1518                 fs->fs_sblockloc = SBLOCK_UFS1;
 1519         }
 1520         if (fs->fs_magic == FS_UFS2_MAGIC && fs->fs_sblockloc != SBLOCK_UFS2 &&
 1521             (fs->fs_flags & FS_FLAGS_UPDATED) == 0) {
 1522                 printf("%s: correcting fs_sblockloc from %jd to %d\n",
 1523                     fs->fs_fsmnt, fs->fs_sblockloc, SBLOCK_UFS2);
 1524                 fs->fs_sblockloc = SBLOCK_UFS2;
 1525         }
 1526         bp = getblk(mp->um_devvp, btodb(fs->fs_sblockloc), (int)fs->fs_sbsize,
 1527             0, 0, 0);
 1528         fs->fs_fmod = 0;
 1529         fs->fs_time = time_second;
 1530         bcopy((caddr_t)fs, bp->b_data, (u_int)fs->fs_sbsize);
 1531         ffs_oldfscompat_write((struct fs *)bp->b_data, mp);
 1532         if (waitfor != MNT_WAIT)
 1533                 bawrite(bp);
 1534         else if ((error = bwrite(bp)) != 0)
 1535                 allerror = error;
 1536         return (allerror);
 1537 }
 1538 
 1539 static int
 1540 ffs_extattrctl(struct mount *mp, int cmd, struct vnode *filename_vp,
 1541         int attrnamespace, const char *attrname, struct thread *td)
 1542 {
 1543 
 1544 #ifdef UFS_EXTATTR
 1545         return (ufs_extattrctl(mp, cmd, filename_vp, attrnamespace,
 1546             attrname, td));
 1547 #else
 1548         return (vfs_stdextattrctl(mp, cmd, filename_vp, attrnamespace,
 1549             attrname, td));
 1550 #endif
 1551 }
 1552 
 1553 static void
 1554 ffs_ifree(struct ufsmount *ump, struct inode *ip)
 1555 {
 1556 
 1557         if (ump->um_fstype == UFS1 && ip->i_din1 != NULL)
 1558                 uma_zfree(uma_ufs1, ip->i_din1);
 1559         else if (ip->i_din2 != NULL)
 1560                 uma_zfree(uma_ufs2, ip->i_din2);
 1561         uma_zfree(uma_inode, ip);
 1562 }

Cache object: 92fc3e7215478e767e535dfa0454fe90


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