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