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 * $FreeBSD: src/sys/ufs/ffs/ffs_vfsops.c,v 1.117.2.10 2002/06/23 22:34:52 iedowse Exp $ 35 * $DragonFly: src/sys/vfs/ufs/ffs_vfsops.c,v 1.58 2008/01/05 14:02:41 swildner Exp $ 36 */ 37 38 #include "opt_quota.h" 39 40 #include <sys/param.h> 41 #include <sys/systm.h> 42 #include <sys/proc.h> 43 #include <sys/nlookup.h> 44 #include <sys/kernel.h> 45 #include <sys/vnode.h> 46 #include <sys/mount.h> 47 #include <sys/buf.h> 48 #include <sys/conf.h> 49 #include <sys/fcntl.h> 50 #include <sys/diskslice.h> 51 #include <sys/malloc.h> 52 53 #include "quota.h" 54 #include "ufsmount.h" 55 #include "inode.h" 56 #include "ufs_extern.h" 57 58 #include "fs.h" 59 #include "ffs_extern.h" 60 61 #include <vm/vm.h> 62 #include <vm/vm_page.h> 63 #include <vm/vm_zone.h> 64 65 static MALLOC_DEFINE(M_FFSNODE, "FFS node", "FFS vnode private part"); 66 67 static int ffs_sbupdate (struct ufsmount *, int); 68 static int ffs_reload (struct mount *, struct ucred *); 69 static int ffs_oldfscompat (struct fs *); 70 static int ffs_mount (struct mount *, char *, caddr_t, struct ucred *); 71 static int ffs_init (struct vfsconf *); 72 73 static struct vfsops ufs_vfsops = { 74 .vfs_mount = ffs_mount, 75 .vfs_unmount = ffs_unmount, 76 .vfs_root = ufs_root, 77 .vfs_quotactl = ufs_quotactl, 78 .vfs_statfs = ffs_statfs, 79 .vfs_sync = ffs_sync, 80 .vfs_vget = ffs_vget, 81 .vfs_fhtovp = ffs_fhtovp, 82 .vfs_checkexp = ufs_check_export, 83 .vfs_vptofh = ffs_vptofh, 84 .vfs_init = ffs_init, 85 .vfs_uninit = ufs_uninit 86 }; 87 88 VFS_SET(ufs_vfsops, ufs, 0); 89 90 extern struct vop_ops ffs_vnode_vops; 91 extern struct vop_ops ffs_spec_vops; 92 extern struct vop_ops ffs_fifo_vops; 93 94 /* 95 * ffs_mount 96 * 97 * Called when mounting local physical media 98 * 99 * PARAMETERS: 100 * mountroot 101 * mp mount point structure 102 * path NULL (flag for root mount!!!) 103 * data <unused> 104 * p process (user credentials check [statfs]) 105 * 106 * mount 107 * mp mount point structure 108 * path path to mount point 109 * data pointer to argument struct in user space 110 * p process (user credentials check) 111 * 112 * RETURNS: 0 Success 113 * !0 error number (errno.h) 114 * 115 * LOCK STATE: 116 * 117 * ENTRY 118 * mount point is locked 119 * EXIT 120 * mount point is locked 121 * 122 * NOTES: 123 * A NULL path can be used for a flag since the mount 124 * system call will fail with EFAULT in copyinstr in 125 * nlookup() if it is a genuine NULL from the user. 126 */ 127 static int 128 ffs_mount(struct mount *mp, /* mount struct pointer */ 129 char *path, /* path to mount point */ 130 caddr_t data, /* arguments to FS specific mount */ 131 struct ucred *cred) /* process requesting mount */ 132 { 133 size_t size; 134 int error; 135 struct vnode *devvp; 136 137 struct ufs_args args; 138 struct ufsmount *ump = 0; 139 struct fs *fs; 140 int flags, ronly = 0; 141 mode_t accessmode; 142 struct nlookupdata nd; 143 struct vnode *rootvp; 144 145 devvp = NULL; 146 error = 0; 147 148 /* 149 * Use NULL path to flag a root mount 150 */ 151 if (path == NULL) { 152 /* 153 *** 154 * Mounting root filesystem 155 *** 156 */ 157 158 if ((error = bdevvp(rootdev, &rootvp))) { 159 kprintf("ffs_mountroot: can't find rootvp\n"); 160 return (error); 161 } 162 163 if( ( error = ffs_mountfs(rootvp, mp, M_FFSNODE)) != 0) { 164 /* fs specific cleanup (if any)*/ 165 goto error_1; 166 } 167 devvp = rootvp; 168 169 goto dostatfs; /* success*/ 170 171 } 172 173 /* 174 *** 175 * Mounting non-root filesystem or updating a filesystem 176 *** 177 */ 178 179 /* copy in user arguments*/ 180 error = copyin(data, (caddr_t)&args, sizeof (struct ufs_args)); 181 if (error) 182 goto error_1; /* can't get arguments*/ 183 184 /* 185 * If updating, check whether changing from read-only to 186 * read/write; if there is no device name, that's all we do. 187 */ 188 if (mp->mnt_flag & MNT_UPDATE) { 189 ump = VFSTOUFS(mp); 190 fs = ump->um_fs; 191 devvp = ump->um_devvp; 192 error = 0; 193 ronly = fs->fs_ronly; /* MNT_RELOAD might change this */ 194 if (ronly == 0 && (mp->mnt_flag & MNT_RDONLY)) { 195 /* 196 * Flush any dirty data. 197 */ 198 VFS_SYNC(mp, MNT_WAIT); 199 /* 200 * Check for and optionally get rid of files open 201 * for writing. 202 */ 203 flags = WRITECLOSE; 204 if (mp->mnt_flag & MNT_FORCE) 205 flags |= FORCECLOSE; 206 if (mp->mnt_flag & MNT_SOFTDEP) { 207 error = softdep_flushfiles(mp, flags); 208 } else { 209 error = ffs_flushfiles(mp, flags); 210 } 211 ronly = 1; 212 } 213 if (!error && (mp->mnt_flag & MNT_RELOAD)) { 214 error = ffs_reload(mp, NULL); 215 } 216 if (error) { 217 goto error_1; 218 } 219 if (ronly && (mp->mnt_kern_flag & MNTK_WANTRDWR)) { 220 /* 221 * If upgrade to read-write by non-root, then verify 222 * that user has necessary permissions on the device. 223 */ 224 if (cred->cr_uid != 0) { 225 vn_lock(devvp, LK_EXCLUSIVE | LK_RETRY); 226 if ((error = VOP_ACCESS(devvp, VREAD | VWRITE, 227 cred)) != 0) { 228 vn_unlock(devvp); 229 return (error); 230 } 231 vn_unlock(devvp); 232 } 233 234 fs->fs_flags &= ~FS_UNCLEAN; 235 if (fs->fs_clean == 0) { 236 fs->fs_flags |= FS_UNCLEAN; 237 if (mp->mnt_flag & MNT_FORCE) { 238 kprintf( 239 "WARNING: %s was not properly dismounted\n", 240 fs->fs_fsmnt); 241 } else { 242 kprintf( 243 "WARNING: R/W mount of %s denied. Filesystem is not clean - run fsck\n", 244 fs->fs_fsmnt); 245 error = EPERM; 246 goto error_1; 247 } 248 } 249 250 /* check to see if we need to start softdep */ 251 if (fs->fs_flags & FS_DOSOFTDEP) { 252 error = softdep_mount(devvp, mp, fs); 253 if (error) 254 goto error_1; 255 } 256 ronly = 0; 257 } 258 /* 259 * Soft updates is incompatible with "async", 260 * so if we are doing softupdates stop the user 261 * from setting the async flag in an update. 262 * Softdep_mount() clears it in an initial mount 263 * or ro->rw remount. 264 */ 265 if (mp->mnt_flag & MNT_SOFTDEP) { 266 mp->mnt_flag &= ~MNT_ASYNC; 267 } 268 /* if not updating name...*/ 269 if (args.fspec == 0) { 270 /* 271 * Process export requests. Jumping to "success" 272 * will return the vfs_export() error code. 273 */ 274 error = vfs_export(mp, &ump->um_export, &args.export); 275 goto success; 276 } 277 } 278 279 /* 280 * Not an update, or updating the name: look up the name 281 * and verify that it refers to a sensible block device. 282 */ 283 devvp = NULL; 284 error = nlookup_init(&nd, args.fspec, UIO_USERSPACE, NLC_FOLLOW); 285 if (error == 0) 286 error = nlookup(&nd); 287 if (error == 0) 288 error = cache_vref(&nd.nl_nch, nd.nl_cred, &devvp); 289 nlookup_done(&nd); 290 if (error) 291 goto error_1; 292 293 if (!vn_isdisk(devvp, &error)) 294 goto error_2; 295 296 /* 297 * If mount by non-root, then verify that user has necessary 298 * permissions on the device. 299 */ 300 if (cred->cr_uid != 0) { 301 accessmode = VREAD; 302 if ((mp->mnt_flag & MNT_RDONLY) == 0) 303 accessmode |= VWRITE; 304 vn_lock(devvp, LK_EXCLUSIVE | LK_RETRY); 305 if ((error = VOP_ACCESS(devvp, accessmode, cred)) != 0) { 306 vput(devvp); 307 return (error); 308 } 309 vn_unlock(devvp); 310 } 311 312 if (mp->mnt_flag & MNT_UPDATE) { 313 /* 314 * UPDATE - make sure the resolved vnode represents the same 315 * device. Note that devvp->v_rdev may be NULL since we 316 * haven't opened it, so compare udev instead. 317 * 318 * Our current open/writecount state is associated with 319 * um_devvp, so continue using um_devvp and throw away devvp. 320 */ 321 if (devvp != ump->um_devvp) { 322 if (devvp->v_umajor == ump->um_devvp->v_umajor && 323 devvp->v_uminor == ump->um_devvp->v_uminor) { 324 vrele(devvp); 325 devvp = ump->um_devvp; 326 } else { 327 kprintf("cannot update mount, udev does" 328 " not match %08x:%08x vs %08x:%08x\n", 329 devvp->v_umajor, devvp->v_uminor, 330 ump->um_devvp->v_umajor, 331 ump->um_devvp->v_uminor); 332 error = EINVAL; /* needs translation */ 333 } 334 } else { 335 vrele(devvp); 336 } 337 /* 338 * Update device name only on success 339 */ 340 if (!error) { 341 /* Save "mounted from" info for mount point (NULL pad)*/ 342 copyinstr( args.fspec, 343 mp->mnt_stat.f_mntfromname, 344 MNAMELEN - 1, 345 &size); 346 bzero( mp->mnt_stat.f_mntfromname + size, MNAMELEN - size); 347 } 348 } else { 349 /* 350 ******************** 351 * NEW MOUNT 352 ******************** 353 */ 354 355 /* Save "mounted from" info for mount point (NULL pad)*/ 356 copyinstr( args.fspec, /* device name*/ 357 mp->mnt_stat.f_mntfromname, /* save area*/ 358 MNAMELEN - 1, /* max size*/ 359 &size); /* real size*/ 360 bzero( mp->mnt_stat.f_mntfromname + size, MNAMELEN - size); 361 362 /* Save "last mounted on" info for mount point (NULL pad)*/ 363 bzero(mp->mnt_stat.f_mntonname, 364 sizeof(mp->mnt_stat.f_mntonname)); 365 if (path) { 366 copyinstr(path, mp->mnt_stat.f_mntonname, 367 sizeof(mp->mnt_stat.f_mntonname) - 1, 368 &size); 369 } 370 371 error = ffs_mountfs(devvp, mp, M_FFSNODE); 372 } 373 if (error) { 374 goto error_2; 375 } 376 377 dostatfs: 378 /* 379 * Initialize FS stat information in mount struct; uses 380 * mp->mnt_stat.f_mntfromname. 381 * 382 * This code is common to root and non-root mounts 383 */ 384 (void)VFS_STATFS(mp, &mp->mnt_stat, cred); 385 386 goto success; 387 388 389 error_2: /* error with devvp held*/ 390 391 /* release devvp before failing*/ 392 vrele(devvp); 393 394 error_1: /* no state to back out*/ 395 396 success: 397 if (!error && path && (mp->mnt_flag & MNT_UPDATE)) { 398 /* Update clean flag after changing read-onlyness. */ 399 fs = ump->um_fs; 400 if (ronly != fs->fs_ronly) { 401 fs->fs_ronly = ronly; 402 fs->fs_clean = ronly && 403 (fs->fs_flags & FS_UNCLEAN) == 0 ? 1 : 0; 404 405 /* 406 * The device must be re-opened as appropriate or 407 * the device close at unmount time will panic. 408 */ 409 vn_lock(devvp, LK_EXCLUSIVE | LK_RETRY); 410 if (ronly) { 411 VOP_OPEN(devvp, FREAD, FSCRED, NULL); 412 VOP_CLOSE(devvp, FREAD|FWRITE); 413 } else { 414 VOP_OPEN(devvp, FREAD|FWRITE, FSCRED, NULL); 415 VOP_CLOSE(devvp, FREAD); 416 } 417 vn_unlock(devvp); 418 ffs_sbupdate(ump, MNT_WAIT); 419 } 420 } 421 return (error); 422 } 423 424 /* 425 * Reload all incore data for a filesystem (used after running fsck on 426 * the root filesystem and finding things to fix). The filesystem must 427 * be mounted read-only. 428 * 429 * Things to do to update the mount: 430 * 1) invalidate all cached meta-data. 431 * 2) re-read superblock from disk. 432 * 3) re-read summary information from disk. 433 * 4) invalidate all inactive vnodes. 434 * 5) invalidate all cached file data. 435 * 6) re-read inode data for all active vnodes. 436 */ 437 438 static int ffs_reload_scan2(struct mount *mp, struct vnode *vp, void *data); 439 440 struct scaninfo { 441 int rescan; 442 struct fs *fs; 443 struct vnode *devvp; 444 int waitfor; 445 int allerror; 446 }; 447 448 static int 449 ffs_reload(struct mount *mp, struct ucred *cred) 450 { 451 struct vnode *devvp; 452 void *space; 453 struct buf *bp; 454 struct fs *fs, *newfs; 455 struct partinfo dpart; 456 cdev_t dev; 457 int i, blks, size, error; 458 struct scaninfo scaninfo; 459 int32_t *lp; 460 461 if ((mp->mnt_flag & MNT_RDONLY) == 0) 462 return (EINVAL); 463 /* 464 * Step 1: invalidate all cached meta-data. 465 */ 466 devvp = VFSTOUFS(mp)->um_devvp; 467 vn_lock(devvp, LK_EXCLUSIVE | LK_RETRY); 468 error = vinvalbuf(devvp, 0, 0, 0); 469 vn_unlock(devvp); 470 if (error) 471 panic("ffs_reload: dirty1"); 472 473 dev = devvp->v_rdev; 474 475 /* 476 * The backing device must be VMIO-capable because we use getblk(). 477 * NOTE: the MFS driver now returns a VMIO-enabled descriptor. 478 */ 479 if (devvp->v_object == NULL) 480 panic("ffs_reload: devvp has no VM object!"); 481 482 /* 483 * Step 2: re-read superblock from disk. 484 */ 485 if (VOP_IOCTL(devvp, DIOCGPART, (caddr_t)&dpart, FREAD, cred) != 0) 486 size = DEV_BSIZE; 487 else 488 size = dpart.media_blksize; 489 if ((error = bread(devvp, SBOFF, SBSIZE, &bp)) != 0) { 490 brelse(bp); 491 return (error); 492 } 493 newfs = (struct fs *)bp->b_data; 494 if (newfs->fs_magic != FS_MAGIC || newfs->fs_bsize > MAXBSIZE || 495 newfs->fs_bsize < sizeof(struct fs)) { 496 brelse(bp); 497 return (EIO); /* XXX needs translation */ 498 } 499 fs = VFSTOUFS(mp)->um_fs; 500 /* 501 * Copy pointer fields back into superblock before copying in XXX 502 * new superblock. These should really be in the ufsmount. XXX 503 * Note that important parameters (eg fs_ncg) are unchanged. 504 */ 505 newfs->fs_csp = fs->fs_csp; 506 newfs->fs_maxcluster = fs->fs_maxcluster; 507 newfs->fs_contigdirs = fs->fs_contigdirs; 508 /* The filesystem is still read-only. */ 509 newfs->fs_ronly = 1; 510 bcopy(newfs, fs, (uint)fs->fs_sbsize); 511 if (fs->fs_sbsize < SBSIZE) 512 bp->b_flags |= B_INVAL; 513 brelse(bp); 514 mp->mnt_maxsymlinklen = fs->fs_maxsymlinklen; 515 ffs_oldfscompat(fs); 516 /* An old fsck may have zeroed these fields, so recheck them. */ 517 if (fs->fs_avgfilesize <= 0) /* XXX */ 518 fs->fs_avgfilesize = AVFILESIZ; /* XXX */ 519 if (fs->fs_avgfpdir <= 0) /* XXX */ 520 fs->fs_avgfpdir = AFPDIR; /* XXX */ 521 522 /* 523 * Step 3: re-read summary information from disk. 524 */ 525 blks = howmany(fs->fs_cssize, fs->fs_fsize); 526 space = fs->fs_csp; 527 for (i = 0; i < blks; i += fs->fs_frag) { 528 size = fs->fs_bsize; 529 if (i + fs->fs_frag > blks) 530 size = (blks - i) * fs->fs_fsize; 531 error = bread(devvp, fsbtodoff(fs, fs->fs_csaddr + i), size, &bp); 532 if (error) { 533 brelse(bp); 534 return (error); 535 } 536 bcopy(bp->b_data, space, (uint)size); 537 space = (char *)space + size; 538 brelse(bp); 539 } 540 /* 541 * We no longer know anything about clusters per cylinder group. 542 */ 543 if (fs->fs_contigsumsize > 0) { 544 lp = fs->fs_maxcluster; 545 for (i = 0; i < fs->fs_ncg; i++) 546 *lp++ = fs->fs_contigsumsize; 547 } 548 549 scaninfo.rescan = 0; 550 scaninfo.fs = fs; 551 scaninfo.devvp = devvp; 552 while (error == 0 && scaninfo.rescan) { 553 scaninfo.rescan = 0; 554 error = vmntvnodescan(mp, VMSC_GETVX, 555 NULL, ffs_reload_scan2, &scaninfo); 556 } 557 return(error); 558 } 559 560 static int 561 ffs_reload_scan2(struct mount *mp, struct vnode *vp, void *data) 562 { 563 struct scaninfo *info = data; 564 struct inode *ip; 565 struct buf *bp; 566 int error; 567 568 /* 569 * Try to recycle 570 */ 571 if (vrecycle(vp)) 572 return(0); 573 574 if (vinvalbuf(vp, 0, 0, 0)) 575 panic("ffs_reload: dirty2"); 576 /* 577 * Step 6: re-read inode data for all active vnodes. 578 */ 579 ip = VTOI(vp); 580 error = bread(info->devvp, 581 fsbtodoff(info->fs, ino_to_fsba(info->fs, ip->i_number)), 582 (int)info->fs->fs_bsize, &bp); 583 if (error) { 584 brelse(bp); 585 return (error); 586 } 587 ip->i_din = *((struct ufs1_dinode *)bp->b_data + 588 ino_to_fsbo(info->fs, ip->i_number)); 589 ip->i_effnlink = ip->i_nlink; 590 brelse(bp); 591 return(0); 592 } 593 594 /* 595 * Common code for mount and mountroot 596 */ 597 int 598 ffs_mountfs(struct vnode *devvp, struct mount *mp, struct malloc_type *mtype) 599 { 600 struct ufsmount *ump; 601 struct buf *bp; 602 struct fs *fs; 603 cdev_t dev; 604 struct partinfo dpart; 605 void *space; 606 int error, i, blks, size, ronly; 607 int32_t *lp; 608 uint64_t maxfilesize; /* XXX */ 609 610 /* 611 * Disallow multiple mounts of the same device. 612 * Disallow mounting of a device that is currently in use 613 * Flush out any old buffers remaining from a previous use. 614 */ 615 error = vfs_mountedon(devvp); 616 if (error) 617 return (error); 618 if (count_udev(devvp->v_umajor, devvp->v_uminor) > 0) 619 return (EBUSY); 620 vn_lock(devvp, LK_EXCLUSIVE | LK_RETRY); 621 error = vinvalbuf(devvp, V_SAVE, 0, 0); 622 vn_unlock(devvp); 623 if (error) 624 return (error); 625 626 ronly = (mp->mnt_flag & MNT_RDONLY) != 0; 627 vn_lock(devvp, LK_EXCLUSIVE | LK_RETRY); 628 error = VOP_OPEN(devvp, ronly ? FREAD : FREAD|FWRITE, FSCRED, NULL); 629 vn_unlock(devvp); 630 if (error) 631 return (error); 632 dev = devvp->v_rdev; 633 if (dev->si_iosize_max != 0) 634 mp->mnt_iosize_max = dev->si_iosize_max; 635 if (mp->mnt_iosize_max > MAXPHYS) 636 mp->mnt_iosize_max = MAXPHYS; 637 638 /* 639 * Filesystem supports native FSMIDs 640 */ 641 mp->mnt_kern_flag |= MNTK_FSMID; 642 643 /* 644 * The backing device must be VMIO-capable because we use getblk(). 645 * NOTE: the MFS driver now returns a VMIO-enabled descriptor. 646 * The VOP_OPEN() call above should have associated a VM object 647 * with devvp. 648 */ 649 if (devvp->v_object == NULL) 650 panic("ffs_reload: devvp has no VM object!"); 651 652 if (VOP_IOCTL(devvp, DIOCGPART, (caddr_t)&dpart, FREAD, proc0.p_ucred) != 0) 653 size = DEV_BSIZE; 654 else 655 size = dpart.media_blksize; 656 657 bp = NULL; 658 ump = NULL; 659 if ((error = bread(devvp, SBOFF, SBSIZE, &bp)) != 0) 660 goto out; 661 fs = (struct fs *)bp->b_data; 662 if (fs->fs_magic != FS_MAGIC || fs->fs_bsize > MAXBSIZE || 663 fs->fs_bsize < sizeof(struct fs)) { 664 error = EINVAL; /* XXX needs translation */ 665 goto out; 666 } 667 fs->fs_fmod = 0; 668 fs->fs_flags &= ~FS_UNCLEAN; 669 if (fs->fs_clean == 0) { 670 fs->fs_flags |= FS_UNCLEAN; 671 if (ronly || (mp->mnt_flag & MNT_FORCE)) { 672 kprintf( 673 "WARNING: %s was not properly dismounted\n", 674 fs->fs_fsmnt); 675 } else { 676 kprintf( 677 "WARNING: R/W mount of %s denied. Filesystem is not clean - run fsck\n", 678 fs->fs_fsmnt); 679 error = EPERM; 680 goto out; 681 } 682 } 683 /* XXX updating 4.2 FFS superblocks trashes rotational layout tables */ 684 if (fs->fs_postblformat == FS_42POSTBLFMT && !ronly) { 685 error = EROFS; /* needs translation */ 686 goto out; 687 } 688 ump = kmalloc(sizeof *ump, M_UFSMNT, M_WAITOK | M_ZERO); 689 ump->um_malloctype = mtype; 690 ump->um_i_effnlink_valid = 1; 691 ump->um_fs = kmalloc((u_long)fs->fs_sbsize, M_UFSMNT, 692 M_WAITOK); 693 bcopy(bp->b_data, ump->um_fs, (uint)fs->fs_sbsize); 694 if (fs->fs_sbsize < SBSIZE) 695 bp->b_flags |= B_INVAL; 696 brelse(bp); 697 bp = NULL; 698 fs = ump->um_fs; 699 fs->fs_ronly = ronly; 700 size = fs->fs_cssize; 701 blks = howmany(size, fs->fs_fsize); 702 if (fs->fs_contigsumsize > 0) 703 size += fs->fs_ncg * sizeof(int32_t); 704 size += fs->fs_ncg * sizeof(uint8_t); 705 space = kmalloc((u_long)size, M_UFSMNT, M_WAITOK); 706 fs->fs_csp = space; 707 for (i = 0; i < blks; i += fs->fs_frag) { 708 size = fs->fs_bsize; 709 if (i + fs->fs_frag > blks) 710 size = (blks - i) * fs->fs_fsize; 711 if ((error = bread(devvp, fsbtodoff(fs, fs->fs_csaddr + i), 712 size, &bp)) != 0) { 713 kfree(fs->fs_csp, M_UFSMNT); 714 goto out; 715 } 716 bcopy(bp->b_data, space, (uint)size); 717 space = (char *)space + size; 718 brelse(bp); 719 bp = NULL; 720 } 721 if (fs->fs_contigsumsize > 0) { 722 fs->fs_maxcluster = lp = space; 723 for (i = 0; i < fs->fs_ncg; i++) 724 *lp++ = fs->fs_contigsumsize; 725 space = lp; 726 } 727 size = fs->fs_ncg * sizeof(uint8_t); 728 fs->fs_contigdirs = (uint8_t *)space; 729 bzero(fs->fs_contigdirs, size); 730 /* Compatibility for old filesystems XXX */ 731 if (fs->fs_avgfilesize <= 0) /* XXX */ 732 fs->fs_avgfilesize = AVFILESIZ; /* XXX */ 733 if (fs->fs_avgfpdir <= 0) /* XXX */ 734 fs->fs_avgfpdir = AFPDIR; /* XXX */ 735 mp->mnt_data = (qaddr_t)ump; 736 mp->mnt_stat.f_fsid.val[0] = fs->fs_id[0]; 737 mp->mnt_stat.f_fsid.val[1] = fs->fs_id[1]; 738 if (fs->fs_id[0] == 0 || fs->fs_id[1] == 0 || 739 vfs_getvfs(&mp->mnt_stat.f_fsid)) 740 vfs_getnewfsid(mp); 741 mp->mnt_maxsymlinklen = fs->fs_maxsymlinklen; 742 mp->mnt_flag |= MNT_LOCAL; 743 ump->um_mountp = mp; 744 ump->um_dev = dev; 745 ump->um_devvp = devvp; 746 ump->um_nindir = fs->fs_nindir; 747 ump->um_bptrtodb = fs->fs_fsbtodb; 748 ump->um_seqinc = fs->fs_frag; 749 for (i = 0; i < MAXQUOTAS; i++) 750 ump->um_quotas[i] = NULLVP; 751 dev->si_mountpoint = mp; 752 ffs_oldfscompat(fs); 753 754 /* restore "last mounted on" here */ 755 bzero(fs->fs_fsmnt, sizeof(fs->fs_fsmnt)); 756 ksnprintf(fs->fs_fsmnt, sizeof(fs->fs_fsmnt), 757 "%s", mp->mnt_stat.f_mntonname); 758 759 if( mp->mnt_flag & MNT_ROOTFS) { 760 /* 761 * Root mount; update timestamp in mount structure. 762 * this will be used by the common root mount code 763 * to update the system clock. 764 */ 765 mp->mnt_time = fs->fs_time; 766 } 767 768 ump->um_savedmaxfilesize = fs->fs_maxfilesize; /* XXX */ 769 maxfilesize = (uint64_t)0x40000000 * fs->fs_bsize - 1; /* XXX */ 770 /* Enforce limit caused by vm object backing (32 bits vm_pindex_t). */ 771 if (maxfilesize > (uint64_t)0x80000000u * PAGE_SIZE - 1) 772 maxfilesize = (uint64_t)0x80000000u * PAGE_SIZE - 1; 773 if (fs->fs_maxfilesize > maxfilesize) /* XXX */ 774 fs->fs_maxfilesize = maxfilesize; /* XXX */ 775 if (ronly == 0) { 776 if ((fs->fs_flags & FS_DOSOFTDEP) && 777 (error = softdep_mount(devvp, mp, fs)) != 0) { 778 kfree(fs->fs_csp, M_UFSMNT); 779 goto out; 780 } 781 fs->fs_fmod = 1; 782 fs->fs_clean = 0; 783 (void) ffs_sbupdate(ump, MNT_WAIT); 784 } 785 vfs_add_vnodeops(mp, &ffs_vnode_vops, &mp->mnt_vn_norm_ops); 786 vfs_add_vnodeops(mp, &ffs_spec_vops, &mp->mnt_vn_spec_ops); 787 vfs_add_vnodeops(mp, &ffs_fifo_vops, &mp->mnt_vn_fifo_ops); 788 789 return (0); 790 out: 791 dev->si_mountpoint = NULL; 792 if (bp) 793 brelse(bp); 794 VOP_CLOSE(devvp, ronly ? FREAD : FREAD|FWRITE); 795 if (ump) { 796 kfree(ump->um_fs, M_UFSMNT); 797 kfree(ump, M_UFSMNT); 798 mp->mnt_data = (qaddr_t)0; 799 } 800 return (error); 801 } 802 803 /* 804 * Sanity checks for old filesystems. 805 * 806 * XXX - goes away some day. 807 */ 808 static int 809 ffs_oldfscompat(struct fs *fs) 810 { 811 fs->fs_npsect = max(fs->fs_npsect, fs->fs_nsect); /* XXX */ 812 fs->fs_interleave = max(fs->fs_interleave, 1); /* XXX */ 813 if (fs->fs_postblformat == FS_42POSTBLFMT) /* XXX */ 814 fs->fs_nrpos = 8; /* XXX */ 815 if (fs->fs_inodefmt < FS_44INODEFMT) { /* XXX */ 816 #if 0 817 int i; /* XXX */ 818 uint64_t sizepb = fs->fs_bsize; /* XXX */ 819 /* XXX */ 820 fs->fs_maxfilesize = fs->fs_bsize * NDADDR - 1; /* XXX */ 821 for (i = 0; i < NIADDR; i++) { /* XXX */ 822 sizepb *= NINDIR(fs); /* XXX */ 823 fs->fs_maxfilesize += sizepb; /* XXX */ 824 } /* XXX */ 825 #endif 826 fs->fs_maxfilesize = (u_quad_t) 1LL << 39; 827 fs->fs_qbmask = ~fs->fs_bmask; /* XXX */ 828 fs->fs_qfmask = ~fs->fs_fmask; /* XXX */ 829 } /* XXX */ 830 return (0); 831 } 832 833 /* 834 * unmount system call 835 */ 836 int 837 ffs_unmount(struct mount *mp, int mntflags) 838 { 839 struct ufsmount *ump; 840 struct fs *fs; 841 int error, flags; 842 843 flags = 0; 844 if (mntflags & MNT_FORCE) { 845 flags |= FORCECLOSE; 846 } 847 if (mp->mnt_flag & MNT_SOFTDEP) { 848 if ((error = softdep_flushfiles(mp, flags)) != 0) 849 return (error); 850 } else { 851 if ((error = ffs_flushfiles(mp, flags)) != 0) 852 return (error); 853 } 854 ump = VFSTOUFS(mp); 855 fs = ump->um_fs; 856 if (fs->fs_ronly == 0) { 857 fs->fs_clean = fs->fs_flags & FS_UNCLEAN ? 0 : 1; 858 error = ffs_sbupdate(ump, MNT_WAIT); 859 if (error) { 860 fs->fs_clean = 0; 861 return (error); 862 } 863 } 864 ump->um_devvp->v_rdev->si_mountpoint = NULL; 865 866 vinvalbuf(ump->um_devvp, V_SAVE, 0, 0); 867 error = VOP_CLOSE(ump->um_devvp, fs->fs_ronly ? FREAD : FREAD|FWRITE); 868 869 vrele(ump->um_devvp); 870 871 kfree(fs->fs_csp, M_UFSMNT); 872 kfree(fs, M_UFSMNT); 873 kfree(ump, M_UFSMNT); 874 mp->mnt_data = (qaddr_t)0; 875 mp->mnt_flag &= ~MNT_LOCAL; 876 return (error); 877 } 878 879 /* 880 * Flush out all the files in a filesystem. 881 */ 882 int 883 ffs_flushfiles(struct mount *mp, int flags) 884 { 885 struct ufsmount *ump; 886 int error; 887 888 ump = VFSTOUFS(mp); 889 #ifdef QUOTA 890 if (mp->mnt_flag & MNT_QUOTA) { 891 int i; 892 error = vflush(mp, 0, SKIPSYSTEM|flags); 893 if (error) 894 return (error); 895 /* Find out how many quota files we have open. */ 896 for (i = 0; i < MAXQUOTAS; i++) { 897 if (ump->um_quotas[i] == NULLVP) 898 continue; 899 ufs_quotaoff(mp, i); 900 } 901 /* 902 * Here we fall through to vflush again to ensure 903 * that we have gotten rid of all the system vnodes. 904 */ 905 } 906 #endif 907 /* 908 * Flush all the files. 909 */ 910 if ((error = vflush(mp, 0, flags)) != 0) 911 return (error); 912 /* 913 * Flush filesystem metadata. 914 */ 915 vn_lock(ump->um_devvp, LK_EXCLUSIVE | LK_RETRY); 916 error = VOP_FSYNC(ump->um_devvp, MNT_WAIT); 917 vn_unlock(ump->um_devvp); 918 return (error); 919 } 920 921 /* 922 * Get filesystem statistics. 923 */ 924 int 925 ffs_statfs(struct mount *mp, struct statfs *sbp, struct ucred *cred) 926 { 927 struct ufsmount *ump; 928 struct fs *fs; 929 930 ump = VFSTOUFS(mp); 931 fs = ump->um_fs; 932 if (fs->fs_magic != FS_MAGIC) 933 panic("ffs_statfs"); 934 sbp->f_bsize = fs->fs_fsize; 935 sbp->f_iosize = fs->fs_bsize; 936 sbp->f_blocks = fs->fs_dsize; 937 sbp->f_bfree = fs->fs_cstotal.cs_nbfree * fs->fs_frag + 938 fs->fs_cstotal.cs_nffree; 939 sbp->f_bavail = freespace(fs, fs->fs_minfree); 940 sbp->f_files = fs->fs_ncg * fs->fs_ipg - ROOTINO; 941 sbp->f_ffree = fs->fs_cstotal.cs_nifree; 942 if (sbp != &mp->mnt_stat) { 943 sbp->f_type = mp->mnt_vfc->vfc_typenum; 944 bcopy((caddr_t)mp->mnt_stat.f_mntfromname, 945 (caddr_t)&sbp->f_mntfromname[0], MNAMELEN); 946 } 947 return (0); 948 } 949 950 /* 951 * Go through the disk queues to initiate sandbagged IO; 952 * go through the inodes to write those that have been modified; 953 * initiate the writing of the super block if it has been modified. 954 * 955 * Note: we are always called with the filesystem marked `MPBUSY'. 956 */ 957 958 959 static int ffs_sync_scan1(struct mount *mp, struct vnode *vp, void *data); 960 static int ffs_sync_scan2(struct mount *mp, struct vnode *vp, void *data); 961 962 int 963 ffs_sync(struct mount *mp, int waitfor) 964 { 965 struct ufsmount *ump = VFSTOUFS(mp); 966 struct fs *fs; 967 int error; 968 struct scaninfo scaninfo; 969 970 fs = ump->um_fs; 971 if (fs->fs_fmod != 0 && fs->fs_ronly != 0) { /* XXX */ 972 kprintf("fs = %s\n", fs->fs_fsmnt); 973 panic("ffs_sync: rofs mod"); 974 } 975 976 /* 977 * Write back each (modified) inode. 978 */ 979 scaninfo.allerror = 0; 980 scaninfo.rescan = 1; 981 scaninfo.waitfor = waitfor; 982 while (scaninfo.rescan) { 983 scaninfo.rescan = 0; 984 vmntvnodescan(mp, VMSC_GETVP|VMSC_NOWAIT, 985 ffs_sync_scan1, ffs_sync_scan2, &scaninfo); 986 } 987 988 /* 989 * Force stale filesystem control information to be flushed. 990 */ 991 if (waitfor != MNT_LAZY) { 992 if (ump->um_mountp->mnt_flag & MNT_SOFTDEP) 993 waitfor = MNT_NOWAIT; 994 vn_lock(ump->um_devvp, LK_EXCLUSIVE | LK_RETRY); 995 if ((error = VOP_FSYNC(ump->um_devvp, waitfor)) != 0) 996 scaninfo.allerror = error; 997 vn_unlock(ump->um_devvp); 998 } 999 #ifdef QUOTA 1000 ufs_qsync(mp); 1001 #endif 1002 /* 1003 * Write back modified superblock. 1004 */ 1005 if (fs->fs_fmod != 0 && (error = ffs_sbupdate(ump, waitfor)) != 0) 1006 scaninfo.allerror = error; 1007 return (scaninfo.allerror); 1008 } 1009 1010 static int 1011 ffs_sync_scan1(struct mount *mp, struct vnode *vp, void *data) 1012 { 1013 struct inode *ip; 1014 1015 /* 1016 * Depend on the mount list's vnode lock to keep things stable 1017 * enough for a quick test. Since there might be hundreds of 1018 * thousands of vnodes, we cannot afford even a subroutine 1019 * call unless there's a good chance that we have work to do. 1020 */ 1021 ip = VTOI(vp); 1022 /* Restart out whole search if this guy is locked 1023 * or is being reclaimed. 1024 */ 1025 if (vp->v_type == VNON || ((ip->i_flag & 1026 (IN_ACCESS | IN_CHANGE | IN_MODIFIED | IN_UPDATE)) == 0 && 1027 RB_EMPTY(&vp->v_rbdirty_tree))) { 1028 return(-1); 1029 } 1030 return(0); 1031 } 1032 1033 static int 1034 ffs_sync_scan2(struct mount *mp, struct vnode *vp, void *data) 1035 { 1036 struct scaninfo *info = data; 1037 struct inode *ip; 1038 int error; 1039 1040 /* 1041 * We have to recheck after having obtained the vnode interlock. 1042 */ 1043 ip = VTOI(vp); 1044 if (vp->v_type == VNON || vp->v_type == VBAD || 1045 ((ip->i_flag & 1046 (IN_ACCESS | IN_CHANGE | IN_MODIFIED | IN_UPDATE)) == 0 && 1047 RB_EMPTY(&vp->v_rbdirty_tree))) { 1048 return(0); 1049 } 1050 if (vp->v_type != VCHR) { 1051 if ((error = VOP_FSYNC(vp, info->waitfor)) != 0) 1052 info->allerror = error; 1053 } else { 1054 /* 1055 * We must reference the vp to prevent it from 1056 * getting ripped out from under ffs_update, since 1057 * we are not holding a vnode lock. 1058 */ 1059 /* ffs_update(vp, waitfor == MNT_WAIT); */ 1060 ffs_update(vp, 0); 1061 } 1062 return(0); 1063 } 1064 1065 /* 1066 * Look up a FFS dinode number to find its incore vnode, otherwise read it 1067 * in from disk. If it is in core, wait for the lock bit to clear, then 1068 * return the inode locked. Detection and handling of mount points must be 1069 * done by the calling routine. 1070 */ 1071 1072 int 1073 ffs_vget(struct mount *mp, ino_t ino, struct vnode **vpp) 1074 { 1075 struct fs *fs; 1076 struct inode *ip; 1077 struct ufsmount *ump; 1078 struct buf *bp; 1079 struct vnode *vp; 1080 cdev_t dev; 1081 int error; 1082 1083 ump = VFSTOUFS(mp); 1084 dev = ump->um_dev; 1085 restart: 1086 if ((*vpp = ufs_ihashget(dev, ino)) != NULL) { 1087 return (0); 1088 } 1089 1090 /* 1091 * If this MALLOC() is performed after the getnewvnode() 1092 * it might block, leaving a vnode with a NULL v_data to be 1093 * found by ffs_sync() if a sync happens to fire right then, 1094 * which will cause a panic because ffs_sync() blindly 1095 * dereferences vp->v_data (as well it should). 1096 * 1097 * XXX this may no longer be true since getnewvnode returns a 1098 * VX locked vnode now. 1099 */ 1100 MALLOC(ip, struct inode *, sizeof(struct inode), 1101 ump->um_malloctype, M_WAITOK); 1102 1103 /* Allocate a new vnode/inode. */ 1104 error = getnewvnode(VT_UFS, mp, &vp, VLKTIMEOUT, LK_CANRECURSE); 1105 if (error) { 1106 *vpp = NULL; 1107 kfree(ip, ump->um_malloctype); 1108 return (error); 1109 } 1110 bzero((caddr_t)ip, sizeof(struct inode)); 1111 ip->i_vnode = vp; 1112 ip->i_fs = fs = ump->um_fs; 1113 ip->i_dev = dev; 1114 ip->i_number = ino; 1115 #ifdef QUOTA 1116 { 1117 int i; 1118 for (i = 0; i < MAXQUOTAS; i++) 1119 ip->i_dquot[i] = NODQUOT; 1120 } 1121 #endif 1122 1123 /* 1124 * Insert it into the inode hash table and check for a collision. 1125 * If a collision occurs, throw away the vnode and try again. 1126 */ 1127 if (ufs_ihashins(ip) != 0) { 1128 kprintf("debug: ufs ihashins collision, retrying inode %ld\n", 1129 (long)ip->i_number); 1130 vp->v_type = VBAD; 1131 vx_put(vp); 1132 kfree(ip, ump->um_malloctype); 1133 goto restart; 1134 } 1135 vp->v_data = ip; 1136 1137 /* Read in the disk contents for the inode, copy into the inode. */ 1138 error = bread(ump->um_devvp, fsbtodoff(fs, ino_to_fsba(fs, ino)), 1139 (int)fs->fs_bsize, &bp); 1140 if (error) { 1141 /* 1142 * The inode does not contain anything useful, so it would 1143 * be misleading to leave it on its hash chain. With mode 1144 * still zero, it will be unlinked and returned to the free 1145 * list by vput(). 1146 */ 1147 vp->v_type = VBAD; 1148 brelse(bp); 1149 vx_put(vp); 1150 *vpp = NULL; 1151 return (error); 1152 } 1153 ip->i_din = *((struct ufs1_dinode *)bp->b_data + ino_to_fsbo(fs, ino)); 1154 if (DOINGSOFTDEP(vp)) 1155 softdep_load_inodeblock(ip); 1156 else 1157 ip->i_effnlink = ip->i_nlink; 1158 bqrelse(bp); 1159 1160 /* 1161 * Initialize the vnode from the inode, check for aliases. 1162 * Note that the underlying vnode may have changed. 1163 */ 1164 error = ufs_vinit(mp, &vp); 1165 if (error) { 1166 vp->v_type = VBAD; 1167 vx_put(vp); 1168 *vpp = NULL; 1169 return (error); 1170 } 1171 /* 1172 * Finish inode initialization now that aliasing has been resolved. 1173 */ 1174 ip->i_devvp = ump->um_devvp; 1175 vref(ip->i_devvp); 1176 /* 1177 * Set up a generation number for this inode if it does not 1178 * already have one. This should only happen on old filesystems. 1179 */ 1180 if (ip->i_gen == 0) { 1181 ip->i_gen = krandom() / 2 + 1; 1182 if ((vp->v_mount->mnt_flag & MNT_RDONLY) == 0) 1183 ip->i_flag |= IN_MODIFIED; 1184 } 1185 /* 1186 * Ensure that uid and gid are correct. This is a temporary 1187 * fix until fsck has been changed to do the update. 1188 */ 1189 if (fs->fs_inodefmt < FS_44INODEFMT) { /* XXX */ 1190 ip->i_uid = ip->i_din.di_ouid; /* XXX */ 1191 ip->i_gid = ip->i_din.di_ogid; /* XXX */ 1192 } /* XXX */ 1193 1194 /* 1195 * return a VX locked and refd vnode (VX == same as normal vget() 1196 * vnode so we are ok) 1197 */ 1198 *vpp = vp; 1199 return (0); 1200 } 1201 1202 /* 1203 * File handle to vnode 1204 * 1205 * Have to be really careful about stale file handles: 1206 * - check that the inode number is valid 1207 * - call ffs_vget() to get the locked inode 1208 * - check for an unallocated inode (i_mode == 0) 1209 * - check that the given client host has export rights and return 1210 * those rights via. exflagsp and credanonp 1211 */ 1212 int 1213 ffs_fhtovp(struct mount *mp, struct fid *fhp, struct vnode **vpp) 1214 { 1215 struct ufid *ufhp; 1216 struct fs *fs; 1217 1218 ufhp = (struct ufid *)fhp; 1219 fs = VFSTOUFS(mp)->um_fs; 1220 if (ufhp->ufid_ino < ROOTINO || 1221 ufhp->ufid_ino >= fs->fs_ncg * fs->fs_ipg) 1222 return (ESTALE); 1223 return (ufs_fhtovp(mp, ufhp, vpp)); 1224 } 1225 1226 /* 1227 * Vnode pointer to File handle 1228 */ 1229 /* ARGSUSED */ 1230 int 1231 ffs_vptofh(struct vnode *vp, struct fid *fhp) 1232 { 1233 struct inode *ip; 1234 struct ufid *ufhp; 1235 1236 ip = VTOI(vp); 1237 ufhp = (struct ufid *)fhp; 1238 ufhp->ufid_len = sizeof(struct ufid); 1239 ufhp->ufid_ino = ip->i_number; 1240 ufhp->ufid_gen = ip->i_gen; 1241 return (0); 1242 } 1243 1244 /* 1245 * Initialize the filesystem; just use ufs_init. 1246 */ 1247 static int 1248 ffs_init(struct vfsconf *vfsp) 1249 { 1250 softdep_initialize(); 1251 return (ufs_init(vfsp)); 1252 } 1253 1254 /* 1255 * Write a superblock and associated information back to disk. 1256 */ 1257 static int 1258 ffs_sbupdate(struct ufsmount *mp, int waitfor) 1259 { 1260 struct fs *dfs, *fs = mp->um_fs; 1261 struct buf *bp; 1262 int blks; 1263 void *space; 1264 int i, size, error, allerror = 0; 1265 1266 /* 1267 * First write back the summary information. 1268 * 1269 * NOTE: the getblk is relative to the device vnode so bio1 1270 * contains the device block number. 1271 */ 1272 blks = howmany(fs->fs_cssize, fs->fs_fsize); 1273 space = fs->fs_csp; 1274 for (i = 0; i < blks; i += fs->fs_frag) { 1275 size = fs->fs_bsize; 1276 if (i + fs->fs_frag > blks) 1277 size = (blks - i) * fs->fs_fsize; 1278 bp = getblk(mp->um_devvp, fsbtodoff(fs, fs->fs_csaddr + i), 1279 size, 0, 0); 1280 bcopy(space, bp->b_data, (uint)size); 1281 space = (char *)space + size; 1282 if (waitfor != MNT_WAIT) 1283 bawrite(bp); 1284 else if ((error = bwrite(bp)) != 0) 1285 allerror = error; 1286 } 1287 /* 1288 * Now write back the superblock itself. If any errors occurred 1289 * up to this point, then fail so that the superblock avoids 1290 * being written out as clean. 1291 */ 1292 if (allerror) 1293 return (allerror); 1294 bp = getblk(mp->um_devvp, SBOFF, (int)fs->fs_sbsize, 0, 0); 1295 fs->fs_fmod = 0; 1296 fs->fs_time = time_second; 1297 bcopy((caddr_t)fs, bp->b_data, (uint)fs->fs_sbsize); 1298 /* Restore compatibility to old filesystems. XXX */ 1299 dfs = (struct fs *)bp->b_data; /* XXX */ 1300 if (fs->fs_postblformat == FS_42POSTBLFMT) /* XXX */ 1301 dfs->fs_nrpos = -1; /* XXX */ 1302 if (fs->fs_inodefmt < FS_44INODEFMT) { /* XXX */ 1303 int32_t *lp, tmp; /* XXX */ 1304 /* XXX */ 1305 lp = (int32_t *)&dfs->fs_qbmask; /* XXX */ 1306 tmp = lp[4]; /* XXX */ 1307 for (i = 4; i > 0; i--) /* XXX */ 1308 lp[i] = lp[i-1]; /* XXX */ 1309 lp[0] = tmp; /* XXX */ 1310 } /* XXX */ 1311 dfs->fs_maxfilesize = mp->um_savedmaxfilesize; /* XXX */ 1312 if (waitfor != MNT_WAIT) 1313 bawrite(bp); 1314 else if ((error = bwrite(bp)) != 0) 1315 allerror = error; 1316 return (allerror); 1317 } 1318