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 cdev_t dev; 462 int i, blks, size, error; 463 struct scaninfo scaninfo; 464 int32_t *lp; 465 466 if ((mp->mnt_flag & MNT_RDONLY) == 0) 467 return (EINVAL); 468 /* 469 * Step 1: invalidate all cached meta-data. 470 */ 471 devvp = VFSTOUFS(mp)->um_devvp; 472 vn_lock(devvp, LK_EXCLUSIVE | LK_RETRY); 473 error = vinvalbuf(devvp, 0, 0, 0); 474 vn_unlock(devvp); 475 if (error) 476 panic("ffs_reload: dirty1"); 477 478 dev = devvp->v_rdev; 479 480 /* 481 * The backing device must be VMIO-capable because we use getblk(). 482 * NOTE: the MFS driver now returns a VMIO-enabled descriptor. 483 */ 484 if (devvp->v_object == NULL) 485 panic("ffs_reload: devvp has no VM object!"); 486 487 /* 488 * Step 2: re-read superblock from disk. 489 */ 490 if (VOP_IOCTL(devvp, DIOCGPART, (caddr_t)&dpart, FREAD, 491 cred, NULL) != 0) { 492 size = DEV_BSIZE; 493 } else { 494 size = dpart.media_blksize; 495 } 496 if ((error = bread(devvp, SBOFF, SBSIZE, &bp)) != 0) { 497 brelse(bp); 498 return (error); 499 } 500 newfs = (struct fs *)bp->b_data; 501 if (newfs->fs_magic != FS_MAGIC || newfs->fs_bsize > MAXBSIZE || 502 newfs->fs_bsize < sizeof(struct fs)) { 503 brelse(bp); 504 return (EIO); /* XXX needs translation */ 505 } 506 fs = VFSTOUFS(mp)->um_fs; 507 /* 508 * Copy pointer fields back into superblock before copying in XXX 509 * new superblock. These should really be in the ufsmount. XXX 510 * Note that important parameters (eg fs_ncg) are unchanged. 511 */ 512 newfs->fs_csp = fs->fs_csp; 513 newfs->fs_maxcluster = fs->fs_maxcluster; 514 newfs->fs_contigdirs = fs->fs_contigdirs; 515 /* The filesystem is still read-only. */ 516 newfs->fs_ronly = 1; 517 bcopy(newfs, fs, (uint)fs->fs_sbsize); 518 if (fs->fs_sbsize < SBSIZE) 519 bp->b_flags |= B_INVAL; 520 brelse(bp); 521 mp->mnt_maxsymlinklen = fs->fs_maxsymlinklen; 522 ffs_oldfscompat(fs); 523 /* An old fsck may have zeroed these fields, so recheck them. */ 524 if (fs->fs_avgfilesize <= 0) /* XXX */ 525 fs->fs_avgfilesize = AVFILESIZ; /* XXX */ 526 if (fs->fs_avgfpdir <= 0) /* XXX */ 527 fs->fs_avgfpdir = AFPDIR; /* XXX */ 528 529 /* 530 * Step 3: re-read summary information from disk. 531 */ 532 blks = howmany(fs->fs_cssize, fs->fs_fsize); 533 space = fs->fs_csp; 534 for (i = 0; i < blks; i += fs->fs_frag) { 535 size = fs->fs_bsize; 536 if (i + fs->fs_frag > blks) 537 size = (blks - i) * fs->fs_fsize; 538 error = bread(devvp, fsbtodoff(fs, fs->fs_csaddr + i), size, &bp); 539 if (error) { 540 brelse(bp); 541 return (error); 542 } 543 bcopy(bp->b_data, space, (uint)size); 544 space = (char *)space + size; 545 brelse(bp); 546 } 547 /* 548 * We no longer know anything about clusters per cylinder group. 549 */ 550 if (fs->fs_contigsumsize > 0) { 551 lp = fs->fs_maxcluster; 552 for (i = 0; i < fs->fs_ncg; i++) 553 *lp++ = fs->fs_contigsumsize; 554 } 555 556 scaninfo.rescan = 0; 557 scaninfo.fs = fs; 558 scaninfo.devvp = devvp; 559 while (error == 0 && scaninfo.rescan) { 560 scaninfo.rescan = 0; 561 error = vmntvnodescan(mp, VMSC_GETVX, 562 NULL, ffs_reload_scan2, &scaninfo); 563 } 564 return(error); 565 } 566 567 static int 568 ffs_reload_scan2(struct mount *mp, struct vnode *vp, void *data) 569 { 570 struct scaninfo *info = data; 571 struct inode *ip; 572 struct buf *bp; 573 int error; 574 575 /* 576 * Try to recycle 577 */ 578 if (vrecycle(vp)) 579 return(0); 580 581 if (vinvalbuf(vp, 0, 0, 0)) 582 panic("ffs_reload: dirty2"); 583 /* 584 * Step 6: re-read inode data for all active vnodes. 585 */ 586 ip = VTOI(vp); 587 error = bread(info->devvp, 588 fsbtodoff(info->fs, ino_to_fsba(info->fs, ip->i_number)), 589 (int)info->fs->fs_bsize, &bp); 590 if (error) { 591 brelse(bp); 592 return (error); 593 } 594 ip->i_din = *((struct ufs1_dinode *)bp->b_data + 595 ino_to_fsbo(info->fs, ip->i_number)); 596 ip->i_effnlink = ip->i_nlink; 597 brelse(bp); 598 return(0); 599 } 600 601 /* 602 * Common code for mount and mountroot 603 */ 604 int 605 ffs_mountfs(struct vnode *devvp, struct mount *mp, struct malloc_type *mtype) 606 { 607 struct ufsmount *ump; 608 struct buf *bp; 609 struct fs *fs; 610 cdev_t dev; 611 struct partinfo dpart; 612 void *space; 613 int error, i, blks, size, ronly; 614 int32_t *lp; 615 uint64_t maxfilesize; /* XXX */ 616 617 /* 618 * Disallow multiple mounts of the same device. 619 * Disallow mounting of a device that is currently in use 620 * Flush out any old buffers remaining from a previous use. 621 */ 622 error = vfs_mountedon(devvp); 623 if (error) 624 return (error); 625 if (vcount(devvp) > 0) 626 return (EBUSY); 627 vn_lock(devvp, LK_EXCLUSIVE | LK_RETRY); 628 error = vinvalbuf(devvp, V_SAVE, 0, 0); 629 vn_unlock(devvp); 630 if (error) 631 return (error); 632 633 ronly = (mp->mnt_flag & MNT_RDONLY) != 0; 634 vn_lock(devvp, LK_EXCLUSIVE | LK_RETRY); 635 error = VOP_OPEN(devvp, ronly ? FREAD : FREAD|FWRITE, FSCRED, NULL); 636 vn_unlock(devvp); 637 if (error) 638 return (error); 639 dev = devvp->v_rdev; 640 if (dev->si_iosize_max != 0) 641 mp->mnt_iosize_max = dev->si_iosize_max; 642 if (mp->mnt_iosize_max > MAXPHYS) 643 mp->mnt_iosize_max = MAXPHYS; 644 645 /* 646 * Filesystem supports native FSMIDs 647 */ 648 mp->mnt_kern_flag |= MNTK_FSMID; 649 650 /* 651 * The backing device must be VMIO-capable because we use getblk(). 652 * NOTE: the MFS driver now returns a VMIO-enabled descriptor. 653 * The VOP_OPEN() call above should have associated a VM object 654 * with devvp. 655 */ 656 if (devvp->v_object == NULL) 657 panic("ffs_reload: devvp has no VM object!"); 658 659 if (VOP_IOCTL(devvp, DIOCGPART, (caddr_t)&dpart, FREAD, 660 proc0.p_ucred, NULL) != 0) { 661 size = DEV_BSIZE; 662 } else { 663 size = dpart.media_blksize; 664 } 665 666 bp = NULL; 667 ump = NULL; 668 if ((error = bread(devvp, SBOFF, SBSIZE, &bp)) != 0) 669 goto out; 670 fs = (struct fs *)bp->b_data; 671 if (fs->fs_magic != FS_MAGIC || fs->fs_bsize > MAXBSIZE || 672 fs->fs_bsize < sizeof(struct fs)) { 673 error = EINVAL; /* XXX needs translation */ 674 goto out; 675 } 676 fs->fs_fmod = 0; 677 fs->fs_flags &= ~FS_UNCLEAN; 678 if (fs->fs_clean == 0) { 679 fs->fs_flags |= FS_UNCLEAN; 680 if (ronly || (mp->mnt_flag & MNT_FORCE)) { 681 kprintf( 682 "WARNING: %s was not properly dismounted\n", 683 fs->fs_fsmnt); 684 } else { 685 kprintf( 686 "WARNING: R/W mount of %s denied. Filesystem is not clean - run fsck\n", 687 fs->fs_fsmnt); 688 error = EPERM; 689 goto out; 690 } 691 } 692 /* XXX updating 4.2 FFS superblocks trashes rotational layout tables */ 693 if (fs->fs_postblformat == FS_42POSTBLFMT && !ronly) { 694 error = EROFS; /* needs translation */ 695 goto out; 696 } 697 ump = kmalloc(sizeof *ump, M_UFSMNT, M_WAITOK | M_ZERO); 698 ump->um_malloctype = mtype; 699 ump->um_i_effnlink_valid = 1; 700 ump->um_fs = kmalloc((u_long)fs->fs_sbsize, M_UFSMNT, 701 M_WAITOK); 702 bcopy(bp->b_data, ump->um_fs, (uint)fs->fs_sbsize); 703 if (fs->fs_sbsize < SBSIZE) 704 bp->b_flags |= B_INVAL; 705 brelse(bp); 706 bp = NULL; 707 fs = ump->um_fs; 708 fs->fs_ronly = ronly; 709 size = fs->fs_cssize; 710 blks = howmany(size, fs->fs_fsize); 711 if (fs->fs_contigsumsize > 0) 712 size += fs->fs_ncg * sizeof(int32_t); 713 size += fs->fs_ncg * sizeof(uint8_t); 714 space = kmalloc((u_long)size, M_UFSMNT, M_WAITOK); 715 fs->fs_csp = space; 716 for (i = 0; i < blks; i += fs->fs_frag) { 717 size = fs->fs_bsize; 718 if (i + fs->fs_frag > blks) 719 size = (blks - i) * fs->fs_fsize; 720 if ((error = bread(devvp, fsbtodoff(fs, fs->fs_csaddr + i), 721 size, &bp)) != 0) { 722 kfree(fs->fs_csp, M_UFSMNT); 723 goto out; 724 } 725 bcopy(bp->b_data, space, (uint)size); 726 space = (char *)space + size; 727 brelse(bp); 728 bp = NULL; 729 } 730 if (fs->fs_contigsumsize > 0) { 731 fs->fs_maxcluster = lp = space; 732 for (i = 0; i < fs->fs_ncg; i++) 733 *lp++ = fs->fs_contigsumsize; 734 space = lp; 735 } 736 size = fs->fs_ncg * sizeof(uint8_t); 737 fs->fs_contigdirs = (uint8_t *)space; 738 bzero(fs->fs_contigdirs, size); 739 /* Compatibility for old filesystems XXX */ 740 if (fs->fs_avgfilesize <= 0) /* XXX */ 741 fs->fs_avgfilesize = AVFILESIZ; /* XXX */ 742 if (fs->fs_avgfpdir <= 0) /* XXX */ 743 fs->fs_avgfpdir = AFPDIR; /* XXX */ 744 mp->mnt_data = (qaddr_t)ump; 745 mp->mnt_stat.f_fsid.val[0] = fs->fs_id[0]; 746 mp->mnt_stat.f_fsid.val[1] = fs->fs_id[1]; 747 if (fs->fs_id[0] == 0 || fs->fs_id[1] == 0 || 748 vfs_getvfs(&mp->mnt_stat.f_fsid)) 749 vfs_getnewfsid(mp); 750 mp->mnt_maxsymlinklen = fs->fs_maxsymlinklen; 751 mp->mnt_flag |= MNT_LOCAL; 752 ump->um_mountp = mp; 753 ump->um_dev = dev; 754 ump->um_devvp = devvp; 755 ump->um_nindir = fs->fs_nindir; 756 ump->um_bptrtodb = fs->fs_fsbtodb; 757 ump->um_seqinc = fs->fs_frag; 758 for (i = 0; i < MAXQUOTAS; i++) 759 ump->um_quotas[i] = NULLVP; 760 dev->si_mountpoint = mp; 761 ffs_oldfscompat(fs); 762 763 /* restore "last mounted on" here */ 764 bzero(fs->fs_fsmnt, sizeof(fs->fs_fsmnt)); 765 ksnprintf(fs->fs_fsmnt, sizeof(fs->fs_fsmnt), 766 "%s", mp->mnt_stat.f_mntonname); 767 768 if( mp->mnt_flag & MNT_ROOTFS) { 769 /* 770 * Root mount; update timestamp in mount structure. 771 * this will be used by the common root mount code 772 * to update the system clock. 773 */ 774 mp->mnt_time = fs->fs_time; 775 } 776 777 ump->um_savedmaxfilesize = fs->fs_maxfilesize; /* XXX */ 778 maxfilesize = (uint64_t)0x40000000 * fs->fs_bsize - 1; /* XXX */ 779 /* Enforce limit caused by vm object backing (32 bits vm_pindex_t). */ 780 if (maxfilesize > (uint64_t)0x80000000u * PAGE_SIZE - 1) 781 maxfilesize = (uint64_t)0x80000000u * PAGE_SIZE - 1; 782 if (fs->fs_maxfilesize > maxfilesize) /* XXX */ 783 fs->fs_maxfilesize = maxfilesize; /* XXX */ 784 if (ronly == 0) { 785 if ((fs->fs_flags & FS_DOSOFTDEP) && 786 (error = softdep_mount(devvp, mp, fs)) != 0) { 787 kfree(fs->fs_csp, M_UFSMNT); 788 goto out; 789 } 790 fs->fs_fmod = 1; 791 fs->fs_clean = 0; 792 (void) ffs_sbupdate(ump, MNT_WAIT); 793 } 794 vfs_add_vnodeops(mp, &ffs_vnode_vops, &mp->mnt_vn_norm_ops); 795 vfs_add_vnodeops(mp, &ffs_spec_vops, &mp->mnt_vn_spec_ops); 796 vfs_add_vnodeops(mp, &ffs_fifo_vops, &mp->mnt_vn_fifo_ops); 797 798 return (0); 799 out: 800 dev->si_mountpoint = NULL; 801 if (bp) 802 brelse(bp); 803 VOP_CLOSE(devvp, ronly ? FREAD : FREAD|FWRITE); 804 if (ump) { 805 kfree(ump->um_fs, M_UFSMNT); 806 kfree(ump, M_UFSMNT); 807 mp->mnt_data = (qaddr_t)0; 808 } 809 return (error); 810 } 811 812 /* 813 * Sanity checks for old filesystems. 814 * 815 * XXX - goes away some day. 816 */ 817 static int 818 ffs_oldfscompat(struct fs *fs) 819 { 820 fs->fs_npsect = max(fs->fs_npsect, fs->fs_nsect); /* XXX */ 821 fs->fs_interleave = max(fs->fs_interleave, 1); /* XXX */ 822 if (fs->fs_postblformat == FS_42POSTBLFMT) /* XXX */ 823 fs->fs_nrpos = 8; /* XXX */ 824 if (fs->fs_inodefmt < FS_44INODEFMT) { /* XXX */ 825 #if 0 826 int i; /* XXX */ 827 uint64_t sizepb = fs->fs_bsize; /* XXX */ 828 /* XXX */ 829 fs->fs_maxfilesize = fs->fs_bsize * NDADDR - 1; /* XXX */ 830 for (i = 0; i < NIADDR; i++) { /* XXX */ 831 sizepb *= NINDIR(fs); /* XXX */ 832 fs->fs_maxfilesize += sizepb; /* XXX */ 833 } /* XXX */ 834 #endif 835 fs->fs_maxfilesize = (u_quad_t) 1LL << 39; 836 fs->fs_qbmask = ~fs->fs_bmask; /* XXX */ 837 fs->fs_qfmask = ~fs->fs_fmask; /* XXX */ 838 } /* XXX */ 839 return (0); 840 } 841 842 /* 843 * unmount system call 844 */ 845 int 846 ffs_unmount(struct mount *mp, int mntflags) 847 { 848 struct ufsmount *ump; 849 struct fs *fs; 850 int error, flags; 851 852 flags = 0; 853 if (mntflags & MNT_FORCE) { 854 flags |= FORCECLOSE; 855 } 856 if (mp->mnt_flag & MNT_SOFTDEP) { 857 if ((error = softdep_flushfiles(mp, flags)) != 0) 858 return (error); 859 } else { 860 if ((error = ffs_flushfiles(mp, flags)) != 0) 861 return (error); 862 } 863 ump = VFSTOUFS(mp); 864 fs = ump->um_fs; 865 if (fs->fs_ronly == 0) { 866 fs->fs_clean = fs->fs_flags & FS_UNCLEAN ? 0 : 1; 867 error = ffs_sbupdate(ump, MNT_WAIT); 868 if (error) { 869 fs->fs_clean = 0; 870 return (error); 871 } 872 } 873 ump->um_devvp->v_rdev->si_mountpoint = NULL; 874 875 vinvalbuf(ump->um_devvp, V_SAVE, 0, 0); 876 error = VOP_CLOSE(ump->um_devvp, fs->fs_ronly ? FREAD : FREAD|FWRITE); 877 878 vrele(ump->um_devvp); 879 880 kfree(fs->fs_csp, M_UFSMNT); 881 kfree(fs, M_UFSMNT); 882 kfree(ump, M_UFSMNT); 883 mp->mnt_data = (qaddr_t)0; 884 mp->mnt_flag &= ~MNT_LOCAL; 885 return (error); 886 } 887 888 /* 889 * Flush out all the files in a filesystem. 890 */ 891 int 892 ffs_flushfiles(struct mount *mp, int flags) 893 { 894 struct ufsmount *ump; 895 int error; 896 897 ump = VFSTOUFS(mp); 898 #ifdef QUOTA 899 if (mp->mnt_flag & MNT_QUOTA) { 900 int i; 901 error = vflush(mp, 0, SKIPSYSTEM|flags); 902 if (error) 903 return (error); 904 /* Find out how many quota files we have open. */ 905 for (i = 0; i < MAXQUOTAS; i++) { 906 if (ump->um_quotas[i] == NULLVP) 907 continue; 908 ufs_quotaoff(mp, i); 909 } 910 /* 911 * Here we fall through to vflush again to ensure 912 * that we have gotten rid of all the system vnodes. 913 */ 914 } 915 #endif 916 /* 917 * Flush all the files. 918 */ 919 if ((error = vflush(mp, 0, flags)) != 0) 920 return (error); 921 /* 922 * Flush filesystem metadata. 923 */ 924 vn_lock(ump->um_devvp, LK_EXCLUSIVE | LK_RETRY); 925 error = VOP_FSYNC(ump->um_devvp, MNT_WAIT, 0); 926 vn_unlock(ump->um_devvp); 927 return (error); 928 } 929 930 /* 931 * Get filesystem statistics. 932 */ 933 int 934 ffs_statfs(struct mount *mp, struct statfs *sbp, struct ucred *cred) 935 { 936 struct ufsmount *ump; 937 struct fs *fs; 938 939 ump = VFSTOUFS(mp); 940 fs = ump->um_fs; 941 if (fs->fs_magic != FS_MAGIC) 942 panic("ffs_statfs"); 943 sbp->f_bsize = fs->fs_fsize; 944 sbp->f_iosize = fs->fs_bsize; 945 sbp->f_blocks = fs->fs_dsize; 946 sbp->f_bfree = fs->fs_cstotal.cs_nbfree * fs->fs_frag + 947 fs->fs_cstotal.cs_nffree; 948 sbp->f_bavail = freespace(fs, fs->fs_minfree); 949 sbp->f_files = fs->fs_ncg * fs->fs_ipg - ROOTINO; 950 sbp->f_ffree = fs->fs_cstotal.cs_nifree; 951 if (sbp != &mp->mnt_stat) { 952 sbp->f_type = mp->mnt_vfc->vfc_typenum; 953 bcopy((caddr_t)mp->mnt_stat.f_mntfromname, 954 (caddr_t)&sbp->f_mntfromname[0], MNAMELEN); 955 } 956 return (0); 957 } 958 959 /* 960 * Go through the disk queues to initiate sandbagged IO; 961 * go through the inodes to write those that have been modified; 962 * initiate the writing of the super block if it has been modified. 963 * 964 * Note: we are always called with the filesystem marked `MPBUSY'. 965 */ 966 967 968 static int ffs_sync_scan1(struct mount *mp, struct vnode *vp, void *data); 969 static int ffs_sync_scan2(struct mount *mp, struct vnode *vp, void *data); 970 971 int 972 ffs_sync(struct mount *mp, int waitfor) 973 { 974 struct ufsmount *ump = VFSTOUFS(mp); 975 struct fs *fs; 976 int error; 977 struct scaninfo scaninfo; 978 979 fs = ump->um_fs; 980 if (fs->fs_fmod != 0 && fs->fs_ronly != 0) { /* XXX */ 981 kprintf("fs = %s\n", fs->fs_fsmnt); 982 panic("ffs_sync: rofs mod"); 983 } 984 985 /* 986 * Write back each (modified) inode. 987 */ 988 scaninfo.allerror = 0; 989 scaninfo.rescan = 1; 990 scaninfo.waitfor = waitfor; 991 while (scaninfo.rescan) { 992 scaninfo.rescan = 0; 993 vmntvnodescan(mp, VMSC_GETVP|VMSC_NOWAIT, 994 ffs_sync_scan1, ffs_sync_scan2, &scaninfo); 995 } 996 997 /* 998 * Force stale filesystem control information to be flushed. 999 */ 1000 if ((waitfor & MNT_LAZY) == 0) { 1001 if (ump->um_mountp->mnt_flag & MNT_SOFTDEP) 1002 waitfor = MNT_NOWAIT; 1003 vn_lock(ump->um_devvp, LK_EXCLUSIVE | LK_RETRY); 1004 if ((error = VOP_FSYNC(ump->um_devvp, waitfor, 0)) != 0) 1005 scaninfo.allerror = error; 1006 vn_unlock(ump->um_devvp); 1007 } 1008 #ifdef QUOTA 1009 ufs_qsync(mp); 1010 #endif 1011 /* 1012 * Write back modified superblock. 1013 */ 1014 if (fs->fs_fmod != 0 && (error = ffs_sbupdate(ump, waitfor)) != 0) 1015 scaninfo.allerror = error; 1016 return (scaninfo.allerror); 1017 } 1018 1019 static int 1020 ffs_sync_scan1(struct mount *mp, struct vnode *vp, void *data) 1021 { 1022 struct inode *ip; 1023 1024 /* 1025 * Depend on the mount list's vnode lock to keep things stable 1026 * enough for a quick test. Since there might be hundreds of 1027 * thousands of vnodes, we cannot afford even a subroutine 1028 * call unless there's a good chance that we have work to do. 1029 */ 1030 ip = VTOI(vp); 1031 /* Restart out whole search if this guy is locked 1032 * or is being reclaimed. 1033 */ 1034 if (vp->v_type == VNON || ((ip->i_flag & 1035 (IN_ACCESS | IN_CHANGE | IN_MODIFIED | IN_UPDATE)) == 0 && 1036 RB_EMPTY(&vp->v_rbdirty_tree))) { 1037 return(-1); 1038 } 1039 return(0); 1040 } 1041 1042 static int 1043 ffs_sync_scan2(struct mount *mp, struct vnode *vp, void *data) 1044 { 1045 struct scaninfo *info = data; 1046 struct inode *ip; 1047 int error; 1048 1049 /* 1050 * We have to recheck after having obtained the vnode interlock. 1051 */ 1052 ip = VTOI(vp); 1053 if (vp->v_type == VNON || vp->v_type == VBAD || 1054 ((ip->i_flag & 1055 (IN_ACCESS | IN_CHANGE | IN_MODIFIED | IN_UPDATE)) == 0 && 1056 RB_EMPTY(&vp->v_rbdirty_tree))) { 1057 return(0); 1058 } 1059 if (vp->v_type != VCHR) { 1060 if ((error = VOP_FSYNC(vp, info->waitfor, 0)) != 0) 1061 info->allerror = error; 1062 } else { 1063 /* 1064 * We must reference the vp to prevent it from 1065 * getting ripped out from under ffs_update, since 1066 * we are not holding a vnode lock. 1067 */ 1068 /* ffs_update(vp, waitfor == MNT_WAIT); */ 1069 ffs_update(vp, 0); 1070 } 1071 return(0); 1072 } 1073 1074 /* 1075 * Look up a FFS dinode number to find its incore vnode, otherwise read it 1076 * in from disk. If it is in core, wait for the lock bit to clear, then 1077 * return the inode locked. Detection and handling of mount points must be 1078 * done by the calling routine. 1079 */ 1080 1081 int 1082 ffs_vget(struct mount *mp, struct vnode *dvp, ino_t ino, struct vnode **vpp) 1083 { 1084 struct fs *fs; 1085 struct inode *ip; 1086 struct ufsmount *ump; 1087 struct buf *bp; 1088 struct vnode *vp; 1089 cdev_t dev; 1090 int error; 1091 1092 ump = VFSTOUFS(mp); 1093 dev = ump->um_dev; 1094 restart: 1095 if ((*vpp = ufs_ihashget(dev, ino)) != NULL) { 1096 return (0); 1097 } 1098 1099 /* 1100 * If this MALLOC() is performed after the getnewvnode() 1101 * it might block, leaving a vnode with a NULL v_data to be 1102 * found by ffs_sync() if a sync happens to fire right then, 1103 * which will cause a panic because ffs_sync() blindly 1104 * dereferences vp->v_data (as well it should). 1105 * 1106 * XXX this may no longer be true since getnewvnode returns a 1107 * VX locked vnode now. 1108 */ 1109 ip = kmalloc(sizeof(struct inode), ump->um_malloctype, M_WAITOK); 1110 1111 /* Allocate a new vnode/inode. */ 1112 error = getnewvnode(VT_UFS, mp, &vp, VLKTIMEOUT, LK_CANRECURSE); 1113 if (error) { 1114 *vpp = NULL; 1115 kfree(ip, ump->um_malloctype); 1116 return (error); 1117 } 1118 bzero((caddr_t)ip, sizeof(struct inode)); 1119 ip->i_vnode = vp; 1120 ip->i_fs = fs = ump->um_fs; 1121 ip->i_dev = dev; 1122 ip->i_number = ino; 1123 #ifdef QUOTA 1124 { 1125 int i; 1126 for (i = 0; i < MAXQUOTAS; i++) 1127 ip->i_dquot[i] = NODQUOT; 1128 } 1129 #endif 1130 1131 /* 1132 * Insert it into the inode hash table and check for a collision. 1133 * If a collision occurs, throw away the vnode and try again. 1134 */ 1135 if (ufs_ihashins(ip) != 0) { 1136 kprintf("debug: ufs ihashins collision, retrying inode %ld\n", 1137 (long)ip->i_number); 1138 vp->v_type = VBAD; 1139 vx_put(vp); 1140 kfree(ip, ump->um_malloctype); 1141 goto restart; 1142 } 1143 vp->v_data = ip; 1144 1145 /* Read in the disk contents for the inode, copy into the inode. */ 1146 error = bread(ump->um_devvp, fsbtodoff(fs, ino_to_fsba(fs, ino)), 1147 (int)fs->fs_bsize, &bp); 1148 if (error) { 1149 /* 1150 * The inode does not contain anything useful, so it would 1151 * be misleading to leave it on its hash chain. With mode 1152 * still zero, it will be unlinked and returned to the free 1153 * list by vput(). 1154 */ 1155 vp->v_type = VBAD; 1156 brelse(bp); 1157 vx_put(vp); 1158 *vpp = NULL; 1159 return (error); 1160 } 1161 ip->i_din = *((struct ufs1_dinode *)bp->b_data + ino_to_fsbo(fs, ino)); 1162 if (DOINGSOFTDEP(vp)) 1163 softdep_load_inodeblock(ip); 1164 else 1165 ip->i_effnlink = ip->i_nlink; 1166 bqrelse(bp); 1167 1168 /* 1169 * Initialize the vnode from the inode, check for aliases. 1170 * Note that the underlying vnode may have changed. 1171 */ 1172 error = ufs_vinit(mp, &vp); 1173 if (error) { 1174 vp->v_type = VBAD; 1175 vx_put(vp); 1176 *vpp = NULL; 1177 return (error); 1178 } 1179 /* 1180 * Finish inode initialization now that aliasing has been resolved. 1181 */ 1182 ip->i_devvp = ump->um_devvp; 1183 vref(ip->i_devvp); 1184 /* 1185 * Set up a generation number for this inode if it does not 1186 * already have one. This should only happen on old filesystems. 1187 */ 1188 if (ip->i_gen == 0) { 1189 ip->i_gen = krandom() / 2 + 1; 1190 if ((vp->v_mount->mnt_flag & MNT_RDONLY) == 0) 1191 ip->i_flag |= IN_MODIFIED; 1192 } 1193 /* 1194 * Ensure that uid and gid are correct. This is a temporary 1195 * fix until fsck has been changed to do the update. 1196 */ 1197 if (fs->fs_inodefmt < FS_44INODEFMT) { /* XXX */ 1198 ip->i_uid = ip->i_din.di_ouid; /* XXX */ 1199 ip->i_gid = ip->i_din.di_ogid; /* XXX */ 1200 } /* XXX */ 1201 1202 /* 1203 * return a VX locked and refd vnode (VX == same as normal vget() 1204 * vnode so we are ok) 1205 */ 1206 *vpp = vp; 1207 return (0); 1208 } 1209 1210 /* 1211 * File handle to vnode 1212 * 1213 * Have to be really careful about stale file handles: 1214 * - check that the inode number is valid 1215 * - call ffs_vget() to get the locked inode 1216 * - check for an unallocated inode (i_mode == 0) 1217 * - check that the given client host has export rights and return 1218 * those rights via. exflagsp and credanonp 1219 */ 1220 int 1221 ffs_fhtovp(struct mount *mp, struct vnode *rootvp, 1222 struct fid *fhp, struct vnode **vpp) 1223 { 1224 struct ufid *ufhp; 1225 struct fs *fs; 1226 1227 ufhp = (struct ufid *)fhp; 1228 fs = VFSTOUFS(mp)->um_fs; 1229 if (ufhp->ufid_ino < ROOTINO || 1230 ufhp->ufid_ino >= fs->fs_ncg * fs->fs_ipg) 1231 return (ESTALE); 1232 return (ufs_fhtovp(mp, rootvp, ufhp, vpp)); 1233 } 1234 1235 /* 1236 * Vnode pointer to File handle 1237 */ 1238 /* ARGSUSED */ 1239 int 1240 ffs_vptofh(struct vnode *vp, struct fid *fhp) 1241 { 1242 struct inode *ip; 1243 struct ufid *ufhp; 1244 1245 ip = VTOI(vp); 1246 ufhp = (struct ufid *)fhp; 1247 ufhp->ufid_len = sizeof(struct ufid); 1248 ufhp->ufid_ino = ip->i_number; 1249 ufhp->ufid_gen = ip->i_gen; 1250 return (0); 1251 } 1252 1253 /* 1254 * Initialize the filesystem; just use ufs_init. 1255 */ 1256 static int 1257 ffs_init(struct vfsconf *vfsp) 1258 { 1259 softdep_initialize(); 1260 kmalloc_raise_limit(M_FFSNODE, 0); 1261 return (ufs_init(vfsp)); 1262 } 1263 1264 /* 1265 * Write a superblock and associated information back to disk. 1266 */ 1267 static int 1268 ffs_sbupdate(struct ufsmount *mp, int waitfor) 1269 { 1270 struct fs *dfs, *fs = mp->um_fs; 1271 struct buf *bp; 1272 int blks; 1273 void *space; 1274 int i, size, error, allerror = 0; 1275 1276 /* 1277 * First write back the summary information. 1278 * 1279 * NOTE: the getblk is relative to the device vnode so bio1 1280 * contains the device block number. 1281 */ 1282 blks = howmany(fs->fs_cssize, fs->fs_fsize); 1283 space = fs->fs_csp; 1284 for (i = 0; i < blks; i += fs->fs_frag) { 1285 size = fs->fs_bsize; 1286 if (i + fs->fs_frag > blks) 1287 size = (blks - i) * fs->fs_fsize; 1288 bp = getblk(mp->um_devvp, fsbtodoff(fs, fs->fs_csaddr + i), 1289 size, 0, 0); 1290 bcopy(space, bp->b_data, (uint)size); 1291 space = (char *)space + size; 1292 if (waitfor != MNT_WAIT) 1293 bawrite(bp); 1294 else if ((error = bwrite(bp)) != 0) 1295 allerror = error; 1296 } 1297 /* 1298 * Now write back the superblock itself. If any errors occurred 1299 * up to this point, then fail so that the superblock avoids 1300 * being written out as clean. 1301 */ 1302 if (allerror) 1303 return (allerror); 1304 bp = getblk(mp->um_devvp, SBOFF, (int)fs->fs_sbsize, 0, 0); 1305 fs->fs_fmod = 0; 1306 fs->fs_time = time_second; 1307 bcopy((caddr_t)fs, bp->b_data, (uint)fs->fs_sbsize); 1308 /* Restore compatibility to old filesystems. XXX */ 1309 dfs = (struct fs *)bp->b_data; /* XXX */ 1310 if (fs->fs_postblformat == FS_42POSTBLFMT) /* XXX */ 1311 dfs->fs_nrpos = -1; /* XXX */ 1312 if (fs->fs_inodefmt < FS_44INODEFMT) { /* XXX */ 1313 int32_t *lp, tmp; /* XXX */ 1314 /* XXX */ 1315 lp = (int32_t *)&dfs->fs_qbmask; /* XXX */ 1316 tmp = lp[4]; /* XXX */ 1317 for (i = 4; i > 0; i--) /* XXX */ 1318 lp[i] = lp[i-1]; /* XXX */ 1319 lp[0] = tmp; /* XXX */ 1320 } /* XXX */ 1321 dfs->fs_maxfilesize = mp->um_savedmaxfilesize; /* XXX */ 1322 if (waitfor != MNT_WAIT) 1323 bawrite(bp); 1324 else if ((error = bwrite(bp)) != 0) 1325 allerror = error; 1326 return (allerror); 1327 } 1328