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.8 (Berkeley) 4/18/94 34 * $Id: ffs_vfsops.c,v 1.37 1996/03/02 03:45:12 dyson 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/socket.h> 46 #include <sys/mount.h> 47 #include <sys/buf.h> 48 #include <sys/mbuf.h> 49 #include <sys/file.h> 50 #include <sys/disklabel.h> 51 #include <sys/ioctl.h> 52 #include <sys/errno.h> 53 #include <sys/malloc.h> 54 55 #include <miscfs/specfs/specdev.h> 56 57 #include <ufs/ufs/quota.h> 58 #include <ufs/ufs/ufsmount.h> 59 #include <ufs/ufs/inode.h> 60 #include <ufs/ufs/ufs_extern.h> 61 62 #include <ufs/ffs/fs.h> 63 #include <ufs/ffs/ffs_extern.h> 64 65 #include <vm/vm.h> 66 #include <vm/vm_param.h> 67 #include <vm/vm_prot.h> 68 #include <vm/vm_page.h> 69 #include <vm/vm_object.h> 70 71 static int ffs_sbupdate __P((struct ufsmount *, int)); 72 static int ffs_reload __P((struct mount *,struct ucred *,struct proc *)); 73 static int ffs_oldfscompat __P((struct fs *)); 74 static int ffs_mount __P((struct mount *, 75 char *, caddr_t, struct nameidata *, struct proc *)); 76 77 struct vfsops ufs_vfsops = { 78 ffs_mount, 79 ufs_start, 80 ffs_unmount, 81 ufs_root, 82 ufs_quotactl, 83 ffs_statfs, 84 ffs_sync, 85 ffs_vget, 86 ffs_fhtovp, 87 ffs_vptofh, 88 ffs_init, 89 }; 90 91 VFS_SET(ufs_vfsops, ufs, MOUNT_UFS, 0); 92 93 extern u_long nextgennumber; 94 95 96 /* 97 * ffs_mount 98 * 99 * Called when mounting local physical media 100 * 101 * PARAMETERS: 102 * mountroot 103 * mp mount point structure 104 * path NULL (flag for root mount!!!) 105 * data <unused> 106 * ndp <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 * ndp mount point namei() return (used for 114 * credentials on reload), reused to look 115 * up block device. 116 * p process (user credentials check) 117 * 118 * RETURNS: 0 Success 119 * !0 error number (errno.h) 120 * 121 * LOCK STATE: 122 * 123 * ENTRY 124 * mount point is locked 125 * EXIT 126 * mount point is locked 127 * 128 * NOTES: 129 * A NULL path can be used for a flag since the mount 130 * system call will fail with EFAULT in copyinstr in 131 * namei() if it is a genuine NULL from the user. 132 */ 133 static int 134 ffs_mount( mp, path, data, ndp, p) 135 register struct mount *mp; /* mount struct pointer*/ 136 char *path; /* path to mount point*/ 137 caddr_t data; /* arguments to FS specific mount*/ 138 struct nameidata *ndp; /* mount point credentials*/ 139 struct proc *p; /* process requesting mount*/ 140 { 141 u_int size; 142 int err = 0; 143 struct vnode *devvp; 144 145 struct ufs_args args; 146 struct ufsmount *ump = 0; 147 register struct fs *fs; 148 int flags; 149 150 /* 151 * Use NULL path to flag a root mount 152 */ 153 if( path == NULL) { 154 /* 155 *** 156 * Mounting root file system 157 *** 158 */ 159 160 /* Get vnode for root device*/ 161 if( bdevvp( rootdev, &rootvp)) 162 panic("ffs_mountroot: can't setup bdevvp for root"); 163 164 /* 165 * FS specific handling 166 */ 167 mp->mnt_flag |= MNT_RDONLY; /* XXX globally applicable?*/ 168 169 /* 170 * Attempt mount 171 */ 172 if( ( err = ffs_mountfs(rootvp, mp, p)) != 0) { 173 /* fs specific cleanup (if any)*/ 174 goto error_1; 175 } 176 177 goto dostatfs; /* success*/ 178 179 } 180 181 /* 182 *** 183 * Mounting non-root file system or updating a file system 184 *** 185 */ 186 187 /* copy in user arguments*/ 188 err = copyin(data, (caddr_t)&args, sizeof (struct ufs_args)); 189 if (err) 190 goto error_1; /* can't get arguments*/ 191 192 /* 193 * If updating, check whether changing from read-only to 194 * read/write; if there is no device name, that's all we do. 195 */ 196 if (mp->mnt_flag & MNT_UPDATE) { 197 ump = VFSTOUFS(mp); 198 fs = ump->um_fs; 199 err = 0; 200 if (fs->fs_ronly == 0 && (mp->mnt_flag & MNT_RDONLY)) { 201 flags = WRITECLOSE; 202 if (mp->mnt_flag & MNT_FORCE) 203 flags |= FORCECLOSE; 204 if (vfs_busy(mp)) { 205 err = EBUSY; 206 goto error_1; 207 } 208 err = ffs_flushfiles(mp, flags, p); 209 vfs_unbusy(mp); 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 (fs->fs_ronly && (mp->mnt_flag & MNT_WANTRDWR)) { 217 if (!fs->fs_clean) { 218 if (mp->mnt_flag & MNT_FORCE) { 219 printf("WARNING: %s was not properly dismounted.\n",fs->fs_fsmnt); 220 } else { 221 printf("WARNING: R/W mount of %s denied. Filesystem is not clean - run fsck.\n", 222 fs->fs_fsmnt); 223 err = EPERM; 224 goto error_1; 225 } 226 } 227 fs->fs_ronly = 0; 228 } 229 if (fs->fs_ronly == 0) { 230 fs->fs_clean = 0; 231 ffs_sbupdate(ump, MNT_WAIT); 232 } 233 /* if not updating name...*/ 234 if (args.fspec == 0) { 235 /* 236 * Process export requests. Jumping to "success" 237 * will return the vfs_export() error code. 238 */ 239 err = vfs_export(mp, &ump->um_export, &args.export); 240 goto success; 241 } 242 } 243 244 /* 245 * Not an update, or updating the name: look up the name 246 * and verify that it refers to a sensible block device. 247 */ 248 NDINIT(ndp, LOOKUP, FOLLOW, UIO_USERSPACE, args.fspec, p); 249 err = namei(ndp); 250 if (err) { 251 /* can't get devvp!*/ 252 goto error_1; 253 } 254 255 devvp = ndp->ni_vp; 256 257 if (devvp->v_type != VBLK) { 258 err = ENOTBLK; 259 goto error_2; 260 } 261 if (major(devvp->v_rdev) >= nblkdev) { 262 err = ENXIO; 263 goto error_2; 264 } 265 if (mp->mnt_flag & MNT_UPDATE) { 266 /* 267 ******************** 268 * UPDATE 269 ******************** 270 */ 271 272 if (devvp != ump->um_devvp) 273 err = EINVAL; /* needs translation */ 274 else 275 vrele(devvp); 276 /* 277 * Update device name only on success 278 */ 279 if( !err) { 280 /* Save "mounted from" info for mount point (NULL pad)*/ 281 copyinstr( args.fspec, 282 mp->mnt_stat.f_mntfromname, 283 MNAMELEN - 1, 284 &size); 285 bzero( mp->mnt_stat.f_mntfromname + size, MNAMELEN - size); 286 } 287 } else { 288 /* 289 ******************** 290 * NEW MOUNT 291 ******************** 292 */ 293 294 /* 295 * Since this is a new mount, we want the names for 296 * the device and the mount point copied in. If an 297 * error occurs, the mountpoint is discarded by the 298 * upper level code. 299 */ 300 /* Save "last mounted on" info for mount point (NULL pad)*/ 301 copyinstr( path, /* mount point*/ 302 mp->mnt_stat.f_mntonname, /* save area*/ 303 MNAMELEN - 1, /* max size*/ 304 &size); /* real size*/ 305 bzero( mp->mnt_stat.f_mntonname + size, MNAMELEN - size); 306 307 /* Save "mounted from" info for mount point (NULL pad)*/ 308 copyinstr( args.fspec, /* device name*/ 309 mp->mnt_stat.f_mntfromname, /* save area*/ 310 MNAMELEN - 1, /* max size*/ 311 &size); /* real size*/ 312 bzero( mp->mnt_stat.f_mntfromname + size, MNAMELEN - size); 313 314 err = ffs_mountfs(devvp, mp, p); 315 } 316 if (err) { 317 goto error_2; 318 } 319 320 dostatfs: 321 /* 322 * Initialize FS stat information in mount struct; uses both 323 * mp->mnt_stat.f_mntonname and mp->mnt_stat.f_mntfromname 324 * 325 * This code is common to root and non-root mounts 326 */ 327 (void)VFS_STATFS(mp, &mp->mnt_stat, p); 328 329 goto success; 330 331 332 error_2: /* error with devvp held*/ 333 334 /* release devvp before failing*/ 335 vrele(devvp); 336 337 error_1: /* no state to back out*/ 338 339 success: 340 return( err); 341 } 342 343 344 /* 345 * Reload all incore data for a filesystem (used after running fsck on 346 * the root filesystem and finding things to fix). The filesystem must 347 * be mounted read-only. 348 * 349 * Things to do to update the mount: 350 * 1) invalidate all cached meta-data. 351 * 2) re-read superblock from disk. 352 * 3) re-read summary information from disk. 353 * 4) invalidate all inactive vnodes. 354 * 5) invalidate all cached file data. 355 * 6) re-read inode data for all active vnodes. 356 */ 357 static int 358 ffs_reload(mp, cred, p) 359 register struct mount *mp; 360 struct ucred *cred; 361 struct proc *p; 362 { 363 register struct vnode *vp, *nvp, *devvp; 364 struct inode *ip; 365 struct csum *space; 366 struct buf *bp; 367 struct fs *fs; 368 int i, blks, size, error; 369 370 if ((mp->mnt_flag & MNT_RDONLY) == 0) 371 return (EINVAL); 372 /* 373 * Step 1: invalidate all cached meta-data. 374 */ 375 devvp = VFSTOUFS(mp)->um_devvp; 376 if (vinvalbuf(devvp, 0, cred, p, 0, 0)) 377 panic("ffs_reload: dirty1"); 378 /* 379 * Step 2: re-read superblock from disk. 380 */ 381 error = bread(devvp, SBLOCK, SBSIZE, NOCRED, &bp); 382 if (error) 383 return (error); 384 fs = (struct fs *)bp->b_data; 385 if (fs->fs_magic != FS_MAGIC || fs->fs_bsize > MAXBSIZE || 386 fs->fs_bsize < sizeof(struct fs)) { 387 brelse(bp); 388 return (EIO); /* XXX needs translation */ 389 } 390 fs = VFSTOUFS(mp)->um_fs; 391 bcopy(&fs->fs_csp[0], &((struct fs *)bp->b_data)->fs_csp[0], 392 sizeof(fs->fs_csp)); 393 bcopy(bp->b_data, fs, (u_int)fs->fs_sbsize); 394 if (fs->fs_sbsize < SBSIZE) 395 bp->b_flags |= B_INVAL; 396 brelse(bp); 397 ffs_oldfscompat(fs); 398 /* 399 * Step 3: re-read summary information from disk. 400 */ 401 blks = howmany(fs->fs_cssize, fs->fs_fsize); 402 space = fs->fs_csp[0]; 403 for (i = 0; i < blks; i += fs->fs_frag) { 404 size = fs->fs_bsize; 405 if (i + fs->fs_frag > blks) 406 size = (blks - i) * fs->fs_fsize; 407 error = bread(devvp, fsbtodb(fs, fs->fs_csaddr + i), size, 408 NOCRED, &bp); 409 if (error) 410 return (error); 411 bcopy(bp->b_data, fs->fs_csp[fragstoblks(fs, i)], (u_int)size); 412 brelse(bp); 413 } 414 loop: 415 for (vp = mp->mnt_vnodelist.lh_first; vp != NULL; vp = nvp) { 416 nvp = vp->v_mntvnodes.le_next; 417 /* 418 * Step 4: invalidate all inactive vnodes. 419 */ 420 if (vp->v_usecount == 0) { 421 vgone(vp); 422 continue; 423 } 424 /* 425 * Step 5: invalidate all cached file data. 426 */ 427 if (vget(vp, 1)) 428 goto loop; 429 if (vinvalbuf(vp, 0, cred, p, 0, 0)) 430 panic("ffs_reload: dirty2"); 431 /* 432 * Step 6: re-read inode data for all active vnodes. 433 */ 434 ip = VTOI(vp); 435 error = 436 bread(devvp, fsbtodb(fs, ino_to_fsba(fs, ip->i_number)), 437 (int)fs->fs_bsize, NOCRED, &bp); 438 if (error) { 439 vput(vp); 440 return (error); 441 } 442 ip->i_din = *((struct dinode *)bp->b_data + 443 ino_to_fsbo(fs, ip->i_number)); 444 brelse(bp); 445 vput(vp); 446 if (vp->v_mount != mp) 447 goto loop; 448 } 449 return (0); 450 } 451 452 /* 453 * Common code for mount and mountroot 454 */ 455 int 456 ffs_mountfs(devvp, mp, p) 457 register struct vnode *devvp; 458 struct mount *mp; 459 struct proc *p; 460 { 461 register struct ufsmount *ump; 462 struct buf *bp; 463 register struct fs *fs; 464 dev_t dev = devvp->v_rdev; 465 struct partinfo dpart; 466 caddr_t base, space; 467 int havepart = 0, blks; 468 int error, i, size; 469 int ronly; 470 u_int strsize; 471 472 /* 473 * Disallow multiple mounts of the same device. 474 * Disallow mounting of a device that is currently in use 475 * (except for root, which might share swap device for miniroot). 476 * Flush out any old buffers remaining from a previous use. 477 */ 478 error = vfs_mountedon(devvp); 479 if (error) 480 return (error); 481 if (vcount(devvp) > 1 && devvp != rootvp) 482 return (EBUSY); 483 error = vinvalbuf(devvp, V_SAVE, p->p_ucred, p, 0, 0); 484 if (error) 485 return (error); 486 487 ronly = (mp->mnt_flag & MNT_RDONLY) != 0; 488 error = VOP_OPEN(devvp, ronly ? FREAD : FREAD|FWRITE, FSCRED, p); 489 if (error) 490 return (error); 491 if (VOP_IOCTL(devvp, DIOCGPART, (caddr_t)&dpart, FREAD, NOCRED, p) != 0) 492 size = DEV_BSIZE; 493 else { 494 havepart = 1; 495 size = dpart.disklab->d_secsize; 496 } 497 498 bp = NULL; 499 ump = NULL; 500 error = bread(devvp, SBLOCK, SBSIZE, NOCRED, &bp); 501 if (error) 502 goto out; 503 fs = (struct fs *)bp->b_data; 504 if (fs->fs_magic != FS_MAGIC || fs->fs_bsize > MAXBSIZE || 505 fs->fs_bsize < sizeof(struct fs)) { 506 error = EINVAL; /* XXX needs translation */ 507 goto out; 508 } 509 if (!fs->fs_clean) { 510 if (ronly || (mp->mnt_flag & MNT_FORCE)) { 511 printf("WARNING: %s was not properly dismounted.\n",fs->fs_fsmnt); 512 } else { 513 printf("WARNING: R/W mount of %s denied. Filesystem is not clean - run fsck.\n",fs->fs_fsmnt); 514 error = EPERM; 515 goto out; 516 } 517 } 518 ump = malloc(sizeof *ump, M_UFSMNT, M_WAITOK); 519 bzero((caddr_t)ump, sizeof *ump); 520 ump->um_fs = malloc((u_long)fs->fs_sbsize, M_UFSMNT, 521 M_WAITOK); 522 bcopy(bp->b_data, ump->um_fs, (u_int)fs->fs_sbsize); 523 if (fs->fs_sbsize < SBSIZE) 524 bp->b_flags |= B_INVAL; 525 brelse(bp); 526 bp = NULL; 527 fs = ump->um_fs; 528 fs->fs_ronly = ronly; 529 if (ronly == 0) { 530 fs->fs_fmod = 1; 531 fs->fs_clean = 0; 532 } 533 blks = howmany(fs->fs_cssize, fs->fs_fsize); 534 base = space = malloc((u_long)fs->fs_cssize, M_UFSMNT, 535 M_WAITOK); 536 for (i = 0; i < blks; i += fs->fs_frag) { 537 size = fs->fs_bsize; 538 if (i + fs->fs_frag > blks) 539 size = (blks - i) * fs->fs_fsize; 540 error = bread(devvp, fsbtodb(fs, fs->fs_csaddr + i), size, 541 NOCRED, &bp); 542 if (error) { 543 free(base, M_UFSMNT); 544 goto out; 545 } 546 bcopy(bp->b_data, space, (u_int)size); 547 fs->fs_csp[fragstoblks(fs, i)] = (struct csum *)space; 548 space += size; 549 brelse(bp); 550 bp = NULL; 551 } 552 mp->mnt_data = (qaddr_t)ump; 553 mp->mnt_stat.f_fsid.val[0] = (long)dev; 554 mp->mnt_stat.f_fsid.val[1] = MOUNT_UFS; 555 mp->mnt_maxsymlinklen = fs->fs_maxsymlinklen; 556 mp->mnt_flag |= MNT_LOCAL; 557 ump->um_mountp = mp; 558 ump->um_dev = dev; 559 ump->um_devvp = devvp; 560 ump->um_nindir = fs->fs_nindir; 561 ump->um_bptrtodb = fs->fs_fsbtodb; 562 ump->um_seqinc = fs->fs_frag; 563 for (i = 0; i < MAXQUOTAS; i++) 564 ump->um_quotas[i] = NULLVP; 565 devvp->v_specflags |= SI_MOUNTEDON; 566 ffs_oldfscompat(fs); 567 568 /* 569 * Set FS local "last mounted on" information (NULL pad) 570 */ 571 copystr( mp->mnt_stat.f_mntonname, /* mount point*/ 572 fs->fs_fsmnt, /* copy area*/ 573 sizeof(fs->fs_fsmnt) - 1, /* max size*/ 574 &strsize); /* real size*/ 575 bzero( fs->fs_fsmnt + strsize, sizeof(fs->fs_fsmnt) - strsize); 576 577 if( mp->mnt_flag & MNT_ROOTFS) { 578 /* 579 * Root mount; update timestamp in mount structure. 580 * this will be used by the common root mount code 581 * to update the system clock. 582 */ 583 mp->mnt_time = fs->fs_time; 584 } 585 if (ronly == 0) 586 ffs_sbupdate(ump, MNT_WAIT); 587 /* 588 * Only VMIO the backing device if the backing device is a real 589 * block device. This excludes the original MFS implementation. 590 */ 591 if ((devvp->v_type == VBLK) && (major(devvp->v_rdev) < nblkdev)) { 592 vn_vmio_open(devvp, p, p->p_ucred); 593 } 594 return (0); 595 out: 596 if (bp) 597 brelse(bp); 598 (void)VOP_CLOSE(devvp, ronly ? FREAD : FREAD|FWRITE, NOCRED, p); 599 if (ump) { 600 free(ump->um_fs, M_UFSMNT); 601 free(ump, M_UFSMNT); 602 mp->mnt_data = (qaddr_t)0; 603 } 604 return (error); 605 } 606 607 /* 608 * Sanity checks for old file systems. 609 * 610 * XXX - goes away some day. 611 */ 612 static int 613 ffs_oldfscompat(fs) 614 struct fs *fs; 615 { 616 617 fs->fs_npsect = max(fs->fs_npsect, fs->fs_nsect); /* XXX */ 618 fs->fs_interleave = max(fs->fs_interleave, 1); /* XXX */ 619 if (fs->fs_postblformat == FS_42POSTBLFMT) /* XXX */ 620 fs->fs_nrpos = 8; /* XXX */ 621 if (fs->fs_inodefmt < FS_44INODEFMT) { /* XXX */ 622 #if 0 623 int i; /* XXX */ 624 quad_t sizepb = fs->fs_bsize; /* XXX */ 625 fs->fs_maxfilesize = fs->fs_bsize * NDADDR - 1; /* XXX */ 626 for (i = 0; i < NIADDR; i++) { /* XXX */ 627 sizepb *= NINDIR(fs); /* XXX */ 628 fs->fs_maxfilesize += sizepb; /* XXX */ 629 } /* XXX */ 630 #endif 631 fs->fs_maxfilesize = (u_quad_t) 1LL << 39; 632 fs->fs_qbmask = ~fs->fs_bmask; /* XXX */ 633 fs->fs_qfmask = ~fs->fs_fmask; /* XXX */ 634 } /* XXX */ 635 return (0); 636 } 637 638 /* 639 * unmount system call 640 */ 641 int 642 ffs_unmount(mp, mntflags, p) 643 struct mount *mp; 644 int mntflags; 645 struct proc *p; 646 { 647 register struct ufsmount *ump; 648 register struct fs *fs; 649 int error, flags, ronly; 650 651 flags = 0; 652 if (mntflags & MNT_FORCE) { 653 flags |= FORCECLOSE; 654 } 655 error = ffs_flushfiles(mp, flags, p); 656 if (error) 657 return (error); 658 ump = VFSTOUFS(mp); 659 fs = ump->um_fs; 660 ronly = fs->fs_ronly; 661 if (!ronly) { 662 fs->fs_clean = 1; 663 ffs_sbupdate(ump, MNT_WAIT); 664 } 665 ump->um_devvp->v_specflags &= ~SI_MOUNTEDON; 666 error = VOP_CLOSE(ump->um_devvp, ronly ? FREAD : FREAD|FWRITE, 667 NOCRED, p); 668 vn_vmio_close(ump->um_devvp); 669 free(fs->fs_csp[0], M_UFSMNT); 670 free(fs, M_UFSMNT); 671 free(ump, M_UFSMNT); 672 mp->mnt_data = (qaddr_t)0; 673 mp->mnt_flag &= ~MNT_LOCAL; 674 return (error); 675 } 676 677 /* 678 * Flush out all the files in a filesystem. 679 */ 680 int 681 ffs_flushfiles(mp, flags, p) 682 register struct mount *mp; 683 int flags; 684 struct proc *p; 685 { 686 register struct ufsmount *ump; 687 int error; 688 689 if (!doforce) 690 flags &= ~FORCECLOSE; 691 ump = VFSTOUFS(mp); 692 #ifdef QUOTA 693 if (mp->mnt_flag & MNT_QUOTA) { 694 int i; 695 error = vflush(mp, NULLVP, SKIPSYSTEM|flags); 696 if (error) 697 return (error); 698 for (i = 0; i < MAXQUOTAS; i++) { 699 if (ump->um_quotas[i] == NULLVP) 700 continue; 701 quotaoff(p, mp, i); 702 } 703 /* 704 * Here we fall through to vflush again to ensure 705 * that we have gotten rid of all the system vnodes. 706 */ 707 } 708 #endif 709 error = vflush(mp, NULLVP, flags); 710 return (error); 711 } 712 713 /* 714 * Get file system statistics. 715 */ 716 int 717 ffs_statfs(mp, sbp, p) 718 struct mount *mp; 719 register struct statfs *sbp; 720 struct proc *p; 721 { 722 register struct ufsmount *ump; 723 register struct fs *fs; 724 725 ump = VFSTOUFS(mp); 726 fs = ump->um_fs; 727 if (fs->fs_magic != FS_MAGIC) 728 panic("ffs_statfs"); 729 sbp->f_type = MOUNT_UFS; 730 sbp->f_bsize = fs->fs_fsize; 731 sbp->f_iosize = fs->fs_bsize; 732 sbp->f_blocks = fs->fs_dsize; 733 sbp->f_bfree = fs->fs_cstotal.cs_nbfree * fs->fs_frag + 734 fs->fs_cstotal.cs_nffree; 735 sbp->f_bavail = freespace(fs, fs->fs_minfree); 736 sbp->f_files = fs->fs_ncg * fs->fs_ipg - ROOTINO; 737 sbp->f_ffree = fs->fs_cstotal.cs_nifree; 738 if (sbp != &mp->mnt_stat) { 739 bcopy((caddr_t)mp->mnt_stat.f_mntonname, 740 (caddr_t)&sbp->f_mntonname[0], MNAMELEN); 741 bcopy((caddr_t)mp->mnt_stat.f_mntfromname, 742 (caddr_t)&sbp->f_mntfromname[0], MNAMELEN); 743 } 744 return (0); 745 } 746 747 /* 748 * Go through the disk queues to initiate sandbagged IO; 749 * go through the inodes to write those that have been modified; 750 * initiate the writing of the super block if it has been modified. 751 * 752 * Note: we are always called with the filesystem marked `MPBUSY'. 753 */ 754 int 755 ffs_sync(mp, waitfor, cred, p) 756 struct mount *mp; 757 int waitfor; 758 struct ucred *cred; 759 struct proc *p; 760 { 761 register struct vnode *vp, *nvp; 762 register struct inode *ip; 763 register struct ufsmount *ump = VFSTOUFS(mp); 764 register struct fs *fs; 765 struct timeval tv; 766 int error, allerror = 0; 767 768 fs = ump->um_fs; 769 /* 770 * Write back modified superblock. 771 * Consistency check that the superblock 772 * is still in the buffer cache. 773 */ 774 if (fs->fs_fmod != 0) { 775 if (fs->fs_ronly != 0) { /* XXX */ 776 printf("fs = %s\n", fs->fs_fsmnt); 777 panic("update: rofs mod"); 778 } 779 fs->fs_fmod = 0; 780 fs->fs_time = time.tv_sec; 781 allerror = ffs_sbupdate(ump, waitfor); 782 } 783 /* 784 * Write back each (modified) inode. 785 */ 786 loop: 787 for (vp = mp->mnt_vnodelist.lh_first; vp != NULL; vp = nvp) { 788 /* 789 * If the vnode that we are about to sync is no longer 790 * associated with this mount point, start over. 791 */ 792 if (vp->v_mount != mp) 793 goto loop; 794 nvp = vp->v_mntvnodes.le_next; 795 if (VOP_ISLOCKED(vp)) 796 continue; 797 ip = VTOI(vp); 798 if ((((ip->i_flag & 799 (IN_ACCESS | IN_CHANGE | IN_MODIFIED | IN_UPDATE)) == 0)) && 800 vp->v_dirtyblkhd.lh_first == NULL) 801 continue; 802 if (vp->v_type != VCHR) { 803 if (vget(vp, 1)) 804 goto loop; 805 error = VOP_FSYNC(vp, cred, waitfor, p); 806 if (error) 807 allerror = error; 808 vput(vp); 809 } else { 810 tv = time; 811 /* VOP_UPDATE(vp, &tv, &tv, waitfor == MNT_WAIT); */ 812 VOP_UPDATE(vp, &tv, &tv, 0); 813 } 814 } 815 /* 816 * Force stale file system control information to be flushed. 817 */ 818 error = VOP_FSYNC(ump->um_devvp, cred, waitfor, p); 819 if (error) 820 allerror = error; 821 #ifdef QUOTA 822 qsync(mp); 823 #endif 824 return (allerror); 825 } 826 827 /* 828 * Look up a FFS dinode number to find its incore vnode, otherwise read it 829 * in from disk. If it is in core, wait for the lock bit to clear, then 830 * return the inode locked. Detection and handling of mount points must be 831 * done by the calling routine. 832 */ 833 static int ffs_inode_hash_lock; 834 835 int 836 ffs_vget(mp, ino, vpp) 837 struct mount *mp; 838 ino_t ino; 839 struct vnode **vpp; 840 { 841 register struct fs *fs; 842 register struct inode *ip; 843 struct ufsmount *ump; 844 struct buf *bp; 845 struct vnode *vp; 846 dev_t dev; 847 int type, error; 848 849 ump = VFSTOUFS(mp); 850 dev = ump->um_dev; 851 restart: 852 if ((*vpp = ufs_ihashget(dev, ino)) != NULL) 853 return (0); 854 855 /* 856 * Lock out the creation of new entries in the FFS hash table in 857 * case getnewvnode() or MALLOC() blocks, otherwise a duplicate 858 * may occur! 859 */ 860 if (ffs_inode_hash_lock) { 861 while (ffs_inode_hash_lock) { 862 ffs_inode_hash_lock = -1; 863 tsleep(&ffs_inode_hash_lock, PVM, "ffsvgt", 0); 864 } 865 goto restart; 866 } 867 ffs_inode_hash_lock = 1; 868 869 /* Allocate a new vnode/inode. */ 870 error = getnewvnode(VT_UFS, mp, ffs_vnodeop_p, &vp); 871 if (error) { 872 if (ffs_inode_hash_lock < 0) 873 wakeup(&ffs_inode_hash_lock); 874 ffs_inode_hash_lock = 0; 875 *vpp = NULL; 876 return (error); 877 } 878 type = ump->um_devvp->v_tag == VT_MFS ? M_MFSNODE : M_FFSNODE; /* XXX */ 879 MALLOC(ip, struct inode *, sizeof(struct inode), type, M_WAITOK); 880 bzero((caddr_t)ip, sizeof(struct inode)); 881 vp->v_data = ip; 882 ip->i_vnode = vp; 883 ip->i_fs = fs = ump->um_fs; 884 ip->i_dev = dev; 885 ip->i_number = ino; 886 #ifdef QUOTA 887 { 888 int i; 889 for (i = 0; i < MAXQUOTAS; i++) 890 ip->i_dquot[i] = NODQUOT; 891 } 892 #endif 893 /* 894 * Put it onto its hash chain and lock it so that other requests for 895 * this inode will block if they arrive while we are sleeping waiting 896 * for old data structures to be purged or for the contents of the 897 * disk portion of this inode to be read. 898 */ 899 ufs_ihashins(ip); 900 901 if (ffs_inode_hash_lock < 0) 902 wakeup(&ffs_inode_hash_lock); 903 ffs_inode_hash_lock = 0; 904 905 /* Read in the disk contents for the inode, copy into the inode. */ 906 error = bread(ump->um_devvp, fsbtodb(fs, ino_to_fsba(fs, ino)), 907 (int)fs->fs_bsize, NOCRED, &bp); 908 if (error) { 909 /* 910 * The inode does not contain anything useful, so it would 911 * be misleading to leave it on its hash chain. With mode 912 * still zero, it will be unlinked and returned to the free 913 * list by vput(). 914 */ 915 brelse(bp); 916 vput(vp); 917 *vpp = NULL; 918 return (error); 919 } 920 ip->i_din = *((struct dinode *)bp->b_data + ino_to_fsbo(fs, ino)); 921 bqrelse(bp); 922 923 /* 924 * Initialize the vnode from the inode, check for aliases. 925 * Note that the underlying vnode may have changed. 926 */ 927 error = ufs_vinit(mp, ffs_specop_p, ffs_fifoop_p, &vp); 928 if (error) { 929 vput(vp); 930 *vpp = NULL; 931 return (error); 932 } 933 /* 934 * Finish inode initialization now that aliasing has been resolved. 935 */ 936 ip->i_devvp = ump->um_devvp; 937 VREF(ip->i_devvp); 938 /* 939 * Set up a generation number for this inode if it does not 940 * already have one. This should only happen on old filesystems. 941 */ 942 if (ip->i_gen == 0) { 943 if (++nextgennumber < (u_long)time.tv_sec) 944 nextgennumber = time.tv_sec; 945 ip->i_gen = nextgennumber; 946 if ((vp->v_mount->mnt_flag & MNT_RDONLY) == 0) 947 ip->i_flag |= IN_MODIFIED; 948 } 949 /* 950 * Ensure that uid and gid are correct. This is a temporary 951 * fix until fsck has been changed to do the update. 952 */ 953 if (fs->fs_inodefmt < FS_44INODEFMT) { /* XXX */ 954 ip->i_uid = ip->i_din.di_ouid; /* XXX */ 955 ip->i_gid = ip->i_din.di_ogid; /* XXX */ 956 } /* XXX */ 957 958 *vpp = vp; 959 return (0); 960 } 961 962 /* 963 * File handle to vnode 964 * 965 * Have to be really careful about stale file handles: 966 * - check that the inode number is valid 967 * - call ffs_vget() to get the locked inode 968 * - check for an unallocated inode (i_mode == 0) 969 * - check that the given client host has export rights and return 970 * those rights via. exflagsp and credanonp 971 */ 972 int 973 ffs_fhtovp(mp, fhp, nam, vpp, exflagsp, credanonp) 974 register struct mount *mp; 975 struct fid *fhp; 976 struct mbuf *nam; 977 struct vnode **vpp; 978 int *exflagsp; 979 struct ucred **credanonp; 980 { 981 register struct ufid *ufhp; 982 struct fs *fs; 983 984 ufhp = (struct ufid *)fhp; 985 fs = VFSTOUFS(mp)->um_fs; 986 if (ufhp->ufid_ino < ROOTINO || 987 ufhp->ufid_ino >= fs->fs_ncg * fs->fs_ipg) 988 return (ESTALE); 989 return (ufs_check_export(mp, ufhp, nam, vpp, exflagsp, credanonp)); 990 } 991 992 /* 993 * Vnode pointer to File handle 994 */ 995 /* ARGSUSED */ 996 int 997 ffs_vptofh(vp, fhp) 998 struct vnode *vp; 999 struct fid *fhp; 1000 { 1001 register struct inode *ip; 1002 register struct ufid *ufhp; 1003 1004 ip = VTOI(vp); 1005 ufhp = (struct ufid *)fhp; 1006 ufhp->ufid_len = sizeof(struct ufid); 1007 ufhp->ufid_ino = ip->i_number; 1008 ufhp->ufid_gen = ip->i_gen; 1009 return (0); 1010 } 1011 1012 /* 1013 * Write a superblock and associated information back to disk. 1014 */ 1015 static int 1016 ffs_sbupdate(mp, waitfor) 1017 struct ufsmount *mp; 1018 int waitfor; 1019 { 1020 register struct fs *fs = mp->um_fs; 1021 register struct buf *bp; 1022 int blks; 1023 caddr_t space; 1024 int i, size, error = 0; 1025 1026 bp = getblk(mp->um_devvp, SBLOCK, (int)fs->fs_sbsize, 0, 0); 1027 bcopy((caddr_t)fs, bp->b_data, (u_int)fs->fs_sbsize); 1028 /* Restore compatibility to old file systems. XXX */ 1029 if (fs->fs_postblformat == FS_42POSTBLFMT) /* XXX */ 1030 ((struct fs *)bp->b_data)->fs_nrpos = -1; /* XXX */ 1031 if (waitfor == MNT_WAIT) 1032 error = bwrite(bp); 1033 else 1034 bawrite(bp); 1035 blks = howmany(fs->fs_cssize, fs->fs_fsize); 1036 space = (caddr_t)fs->fs_csp[0]; 1037 for (i = 0; i < blks; i += fs->fs_frag) { 1038 size = fs->fs_bsize; 1039 if (i + fs->fs_frag > blks) 1040 size = (blks - i) * fs->fs_fsize; 1041 bp = getblk(mp->um_devvp, fsbtodb(fs, fs->fs_csaddr + i), 1042 size, 0, 0); 1043 bcopy(space, bp->b_data, (u_int)size); 1044 space += size; 1045 if (waitfor == MNT_WAIT) 1046 error = bwrite(bp); 1047 else 1048 bawrite(bp); 1049 } 1050 return (error); 1051 } 1052