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