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