1 /* 2 * Copyright (c) 1989, 1991, 1993, 1994 3 * The Regents of the University of California. All rights reserved. 4 * 5 * %sccs.include.redist.c% 6 * 7 * @(#)ffs_vfsops.c 8.26 (Berkeley) 05/10/95 8 */ 9 10 #include <sys/param.h> 11 #include <sys/systm.h> 12 #include <sys/namei.h> 13 #include <sys/proc.h> 14 #include <sys/kernel.h> 15 #include <sys/vnode.h> 16 #include <sys/socket.h> 17 #include <sys/mount.h> 18 #include <sys/buf.h> 19 #include <sys/mbuf.h> 20 #include <sys/file.h> 21 #include <sys/disklabel.h> 22 #include <sys/ioctl.h> 23 #include <sys/errno.h> 24 #include <sys/malloc.h> 25 26 #include <miscfs/specfs/specdev.h> 27 28 #include <ufs/ufs/quota.h> 29 #include <ufs/ufs/ufsmount.h> 30 #include <ufs/ufs/inode.h> 31 #include <ufs/ufs/ufs_extern.h> 32 33 #include <ufs/ffs/fs.h> 34 #include <ufs/ffs/ffs_extern.h> 35 36 int ffs_sbupdate __P((struct ufsmount *, int)); 37 38 struct vfsops ufs_vfsops = { 39 ffs_mount, 40 ufs_start, 41 ffs_unmount, 42 ufs_root, 43 ufs_quotactl, 44 ffs_statfs, 45 ffs_sync, 46 ffs_vget, 47 ffs_fhtovp, 48 ffs_vptofh, 49 ffs_init, 50 ffs_sysctl, 51 }; 52 53 extern u_long nextgennumber; 54 55 /* 56 * Called by main() when ufs is going to be mounted as root. 57 */ 58 ffs_mountroot() 59 { 60 extern struct vnode *rootvp; 61 struct fs *fs; 62 struct mount *mp; 63 struct proc *p = curproc; /* XXX */ 64 struct ufsmount *ump; 65 u_int size; 66 int error; 67 68 /* 69 * Get vnodes for swapdev and rootdev. 70 */ 71 if (bdevvp(swapdev, &swapdev_vp) || bdevvp(rootdev, &rootvp)) 72 panic("ffs_mountroot: can't setup bdevvp's"); 73 74 if (error = vfs_rootmountalloc("ufs", "root_device", &mp)) 75 return (error); 76 if (error = ffs_mountfs(rootvp, mp, p)) { 77 mp->mnt_vfc->vfc_refcount--; 78 free(mp, M_MOUNT); 79 return (error); 80 } 81 if (error = vfs_lock(mp)) { 82 (void)ffs_unmount(mp, 0, p); 83 mp->mnt_vfc->vfc_refcount--; 84 free(mp, M_MOUNT); 85 return (error); 86 } 87 CIRCLEQ_INSERT_TAIL(&mountlist, mp, mnt_list); 88 ump = VFSTOUFS(mp); 89 fs = ump->um_fs; 90 (void) copystr(mp->mnt_stat.f_mntonname, fs->fs_fsmnt, MNAMELEN - 1, 0); 91 (void)ffs_statfs(mp, &mp->mnt_stat, p); 92 vfs_unlock(mp); 93 inittodr(fs->fs_time); 94 return (0); 95 } 96 97 /* 98 * VFS Operations. 99 * 100 * mount system call 101 */ 102 int 103 ffs_mount(mp, path, data, ndp, p) 104 register struct mount *mp; 105 char *path; 106 caddr_t data; 107 struct nameidata *ndp; 108 struct proc *p; 109 { 110 struct vnode *devvp; 111 struct ufs_args args; 112 struct ufsmount *ump; 113 register struct fs *fs; 114 u_int size; 115 int error, flags; 116 mode_t accessmode; 117 118 if (error = copyin(data, (caddr_t)&args, sizeof (struct ufs_args))) 119 return (error); 120 /* 121 * If updating, check whether changing from read-only to 122 * read/write; if there is no device name, that's all we do. 123 */ 124 if (mp->mnt_flag & MNT_UPDATE) { 125 ump = VFSTOUFS(mp); 126 fs = ump->um_fs; 127 if (fs->fs_ronly == 0 && (mp->mnt_flag & MNT_RDONLY)) { 128 flags = WRITECLOSE; 129 if (mp->mnt_flag & MNT_FORCE) 130 flags |= FORCECLOSE; 131 if (vfs_busy(mp)) 132 return (EBUSY); 133 if (error = ffs_flushfiles(mp, flags, p)) { 134 vfs_unbusy(mp); 135 return (error); 136 } 137 fs->fs_clean = 1; 138 fs->fs_ronly = 1; 139 if (error = ffs_sbupdate(ump, MNT_WAIT)) { 140 fs->fs_clean = 0; 141 fs->fs_ronly = 0; 142 vfs_unbusy(mp); 143 return (error); 144 } 145 vfs_unbusy(mp); 146 } 147 if ((mp->mnt_flag & MNT_RELOAD) && 148 (error = ffs_reload(mp, ndp->ni_cnd.cn_cred, p))) 149 return (error); 150 if (fs->fs_ronly && (mp->mnt_flag & MNT_WANTRDWR)) { 151 /* 152 * If upgrade to read-write by non-root, then verify 153 * that user has necessary permissions on the device. 154 */ 155 if (p->p_ucred->cr_uid != 0) { 156 devvp = ump->um_devvp; 157 VOP_LOCK(devvp); 158 if (error = VOP_ACCESS(devvp, VREAD | VWRITE, 159 p->p_ucred, p)) { 160 VOP_UNLOCK(devvp); 161 return (error); 162 } 163 VOP_UNLOCK(devvp); 164 } 165 fs->fs_ronly = 0; 166 fs->fs_clean = 0; 167 (void) ffs_sbupdate(ump, MNT_WAIT); 168 } 169 if (args.fspec == 0) { 170 /* 171 * Process export requests. 172 */ 173 return (vfs_export(mp, &ump->um_export, &args.export)); 174 } 175 } 176 /* 177 * Not an update, or updating the name: look up the name 178 * and verify that it refers to a sensible block device. 179 */ 180 NDINIT(ndp, LOOKUP, FOLLOW, UIO_USERSPACE, args.fspec, p); 181 if (error = namei(ndp)) 182 return (error); 183 devvp = ndp->ni_vp; 184 185 if (devvp->v_type != VBLK) { 186 vrele(devvp); 187 return (ENOTBLK); 188 } 189 if (major(devvp->v_rdev) >= nblkdev) { 190 vrele(devvp); 191 return (ENXIO); 192 } 193 /* 194 * If mount by non-root, then verify that user has necessary 195 * permissions on the device. 196 */ 197 if (p->p_ucred->cr_uid != 0) { 198 accessmode = VREAD; 199 if ((mp->mnt_flag & MNT_RDONLY) == 0) 200 accessmode |= VWRITE; 201 VOP_LOCK(devvp); 202 if (error = VOP_ACCESS(devvp, accessmode, p->p_ucred, p)) { 203 vput(devvp); 204 return (error); 205 } 206 VOP_UNLOCK(devvp); 207 } 208 if ((mp->mnt_flag & MNT_UPDATE) == 0) 209 error = ffs_mountfs(devvp, mp, p); 210 else { 211 if (devvp != ump->um_devvp) 212 error = EINVAL; /* needs translation */ 213 else 214 vrele(devvp); 215 } 216 if (error) { 217 vrele(devvp); 218 return (error); 219 } 220 ump = VFSTOUFS(mp); 221 fs = ump->um_fs; 222 (void) copyinstr(path, fs->fs_fsmnt, sizeof(fs->fs_fsmnt) - 1, &size); 223 bzero(fs->fs_fsmnt + size, sizeof(fs->fs_fsmnt) - size); 224 bcopy((caddr_t)fs->fs_fsmnt, (caddr_t)mp->mnt_stat.f_mntonname, 225 MNAMELEN); 226 (void) copyinstr(args.fspec, mp->mnt_stat.f_mntfromname, MNAMELEN - 1, 227 &size); 228 bzero(mp->mnt_stat.f_mntfromname + size, MNAMELEN - size); 229 (void)ffs_statfs(mp, &mp->mnt_stat, p); 230 return (0); 231 } 232 233 /* 234 * Reload all incore data for a filesystem (used after running fsck on 235 * the root filesystem and finding things to fix). The filesystem must 236 * be mounted read-only. 237 * 238 * Things to do to update the mount: 239 * 1) invalidate all cached meta-data. 240 * 2) re-read superblock from disk. 241 * 3) re-read summary information from disk. 242 * 4) invalidate all inactive vnodes. 243 * 5) invalidate all cached file data. 244 * 6) re-read inode data for all active vnodes. 245 */ 246 ffs_reload(mountp, cred, p) 247 register struct mount *mountp; 248 struct ucred *cred; 249 struct proc *p; 250 { 251 register struct vnode *vp, *nvp, *devvp; 252 struct inode *ip; 253 struct csum *space; 254 struct buf *bp; 255 struct fs *fs, *newfs; 256 struct partinfo dpart; 257 int i, blks, size, error; 258 int32_t *lp; 259 260 if ((mountp->mnt_flag & MNT_RDONLY) == 0) 261 return (EINVAL); 262 /* 263 * Step 1: invalidate all cached meta-data. 264 */ 265 devvp = VFSTOUFS(mountp)->um_devvp; 266 if (vinvalbuf(devvp, 0, cred, p, 0, 0)) 267 panic("ffs_reload: dirty1"); 268 /* 269 * Step 2: re-read superblock from disk. 270 */ 271 if (VOP_IOCTL(devvp, DIOCGPART, (caddr_t)&dpart, FREAD, NOCRED, p) != 0) 272 size = DEV_BSIZE; 273 else 274 size = dpart.disklab->d_secsize; 275 if (error = bread(devvp, (ufs_daddr_t)(SBOFF/size), SBSIZE, NOCRED,&bp)) 276 return (error); 277 newfs = (struct fs *)bp->b_data; 278 if (newfs->fs_magic != FS_MAGIC || newfs->fs_bsize > MAXBSIZE || 279 newfs->fs_bsize < sizeof(struct fs)) { 280 brelse(bp); 281 return (EIO); /* XXX needs translation */ 282 } 283 fs = VFSTOUFS(mountp)->um_fs; 284 /* 285 * Copy pointer fields back into superblock before copying in XXX 286 * new superblock. These should really be in the ufsmount. XXX 287 * Note that important parameters (eg fs_ncg) are unchanged. 288 */ 289 bcopy(&fs->fs_csp[0], &newfs->fs_csp[0], sizeof(fs->fs_csp)); 290 newfs->fs_maxcluster = fs->fs_maxcluster; 291 bcopy(newfs, fs, (u_int)fs->fs_sbsize); 292 if (fs->fs_sbsize < SBSIZE) 293 bp->b_flags |= B_INVAL; 294 brelse(bp); 295 mountp->mnt_maxsymlinklen = fs->fs_maxsymlinklen; 296 ffs_oldfscompat(fs); 297 /* 298 * Step 3: re-read summary information from disk. 299 */ 300 blks = howmany(fs->fs_cssize, fs->fs_fsize); 301 space = fs->fs_csp[0]; 302 for (i = 0; i < blks; i += fs->fs_frag) { 303 size = fs->fs_bsize; 304 if (i + fs->fs_frag > blks) 305 size = (blks - i) * fs->fs_fsize; 306 if (error = bread(devvp, fsbtodb(fs, fs->fs_csaddr + i), size, 307 NOCRED, &bp)) 308 return (error); 309 bcopy(bp->b_data, fs->fs_csp[fragstoblks(fs, i)], (u_int)size); 310 brelse(bp); 311 } 312 /* 313 * We no longer know anything about clusters per cylinder group. 314 */ 315 if (fs->fs_contigsumsize > 0) { 316 lp = fs->fs_maxcluster; 317 for (i = 0; i < fs->fs_ncg; i++) 318 *lp++ = fs->fs_contigsumsize; 319 } 320 loop: 321 for (vp = mountp->mnt_vnodelist.lh_first; vp != NULL; vp = nvp) { 322 nvp = vp->v_mntvnodes.le_next; 323 /* 324 * Step 4: invalidate all inactive vnodes. 325 */ 326 if (vp->v_usecount == 0) { 327 vgone(vp); 328 continue; 329 } 330 /* 331 * Step 5: invalidate all cached file data. 332 */ 333 if (vget(vp, 1)) 334 goto loop; 335 if (vinvalbuf(vp, 0, cred, p, 0, 0)) 336 panic("ffs_reload: dirty2"); 337 /* 338 * Step 6: re-read inode data for all active vnodes. 339 */ 340 ip = VTOI(vp); 341 if (error = 342 bread(devvp, fsbtodb(fs, ino_to_fsba(fs, ip->i_number)), 343 (int)fs->fs_bsize, NOCRED, &bp)) { 344 vput(vp); 345 return (error); 346 } 347 ip->i_din = *((struct dinode *)bp->b_data + 348 ino_to_fsbo(fs, ip->i_number)); 349 brelse(bp); 350 vput(vp); 351 if (vp->v_mount != mountp) 352 goto loop; 353 } 354 return (0); 355 } 356 357 /* 358 * Common code for mount and mountroot 359 */ 360 int 361 ffs_mountfs(devvp, mp, p) 362 register struct vnode *devvp; 363 struct mount *mp; 364 struct proc *p; 365 { 366 register struct ufsmount *ump; 367 struct buf *bp; 368 register struct fs *fs; 369 dev_t dev; 370 struct partinfo dpart; 371 caddr_t base, space; 372 int error, i, blks, size, ronly; 373 int32_t *lp; 374 struct ucred *cred; 375 extern struct vnode *rootvp; 376 u_int64_t maxfilesize; /* XXX */ 377 378 dev = devvp->v_rdev; 379 cred = p ? p->p_ucred : NOCRED; 380 /* 381 * Disallow multiple mounts of the same device. 382 * Disallow mounting of a device that is currently in use 383 * (except for root, which might share swap device for miniroot). 384 * Flush out any old buffers remaining from a previous use. 385 */ 386 if (error = vfs_mountedon(devvp)) 387 return (error); 388 if (vcount(devvp) > 1 && devvp != rootvp) 389 return (EBUSY); 390 if (error = vinvalbuf(devvp, V_SAVE, cred, p, 0, 0)) 391 return (error); 392 393 ronly = (mp->mnt_flag & MNT_RDONLY) != 0; 394 if (error = VOP_OPEN(devvp, ronly ? FREAD : FREAD|FWRITE, FSCRED, p)) 395 return (error); 396 if (VOP_IOCTL(devvp, DIOCGPART, (caddr_t)&dpart, FREAD, cred, p) != 0) 397 size = DEV_BSIZE; 398 else 399 size = dpart.disklab->d_secsize; 400 401 bp = NULL; 402 ump = NULL; 403 if (error = bread(devvp, (ufs_daddr_t)(SBOFF/size), SBSIZE, cred, &bp)) 404 goto out; 405 fs = (struct fs *)bp->b_data; 406 if (fs->fs_magic != FS_MAGIC || fs->fs_bsize > MAXBSIZE || 407 fs->fs_bsize < sizeof(struct fs)) { 408 error = EINVAL; /* XXX needs translation */ 409 goto out; 410 } 411 /* XXX updating 4.2 FFS superblocks trashes rotational layout tables */ 412 if (fs->fs_postblformat == FS_42POSTBLFMT && !ronly) { 413 error = EROFS; /* needs translation */ 414 goto out; 415 } 416 ump = malloc(sizeof *ump, M_UFSMNT, M_WAITOK); 417 bzero((caddr_t)ump, sizeof *ump); 418 ump->um_fs = malloc((u_long)fs->fs_sbsize, M_UFSMNT, 419 M_WAITOK); 420 bcopy(bp->b_data, ump->um_fs, (u_int)fs->fs_sbsize); 421 if (fs->fs_sbsize < SBSIZE) 422 bp->b_flags |= B_INVAL; 423 brelse(bp); 424 bp = NULL; 425 fs = ump->um_fs; 426 fs->fs_ronly = ronly; 427 size = fs->fs_cssize; 428 blks = howmany(size, fs->fs_fsize); 429 if (fs->fs_contigsumsize > 0) 430 size += fs->fs_ncg * sizeof(int32_t); 431 base = space = malloc((u_long)size, M_UFSMNT, M_WAITOK); 432 for (i = 0; i < blks; i += fs->fs_frag) { 433 size = fs->fs_bsize; 434 if (i + fs->fs_frag > blks) 435 size = (blks - i) * fs->fs_fsize; 436 if (error = bread(devvp, fsbtodb(fs, fs->fs_csaddr + i), size, 437 cred, &bp)) { 438 free(base, M_UFSMNT); 439 goto out; 440 } 441 bcopy(bp->b_data, space, (u_int)size); 442 fs->fs_csp[fragstoblks(fs, i)] = (struct csum *)space; 443 space += size; 444 brelse(bp); 445 bp = NULL; 446 } 447 if (fs->fs_contigsumsize > 0) { 448 fs->fs_maxcluster = lp = (int32_t *)space; 449 for (i = 0; i < fs->fs_ncg; i++) 450 *lp++ = fs->fs_contigsumsize; 451 } 452 mp->mnt_data = (qaddr_t)ump; 453 mp->mnt_stat.f_fsid.val[0] = (long)dev; 454 mp->mnt_stat.f_fsid.val[1] = mp->mnt_vfc->vfc_typenum; 455 mp->mnt_maxsymlinklen = fs->fs_maxsymlinklen; 456 ump->um_mountp = mp; 457 ump->um_dev = dev; 458 ump->um_devvp = devvp; 459 ump->um_nindir = fs->fs_nindir; 460 ump->um_bptrtodb = fs->fs_fsbtodb; 461 ump->um_seqinc = fs->fs_frag; 462 for (i = 0; i < MAXQUOTAS; i++) 463 ump->um_quotas[i] = NULLVP; 464 devvp->v_specflags |= SI_MOUNTEDON; 465 ffs_oldfscompat(fs); 466 ump->um_savedmaxfilesize = fs->fs_maxfilesize; /* XXX */ 467 maxfilesize = (u_int64_t)0x40000000 * fs->fs_bsize - 1; /* XXX */ 468 if (fs->fs_maxfilesize > maxfilesize) /* XXX */ 469 fs->fs_maxfilesize = maxfilesize; /* XXX */ 470 if (ronly == 0) { 471 fs->fs_clean = 0; 472 (void) ffs_sbupdate(ump, MNT_WAIT); 473 } 474 return (0); 475 out: 476 if (bp) 477 brelse(bp); 478 (void)VOP_CLOSE(devvp, ronly ? FREAD : FREAD|FWRITE, cred, p); 479 if (ump) { 480 free(ump->um_fs, M_UFSMNT); 481 free(ump, M_UFSMNT); 482 mp->mnt_data = (qaddr_t)0; 483 } 484 return (error); 485 } 486 487 /* 488 * Sanity checks for old file systems. 489 * 490 * XXX - goes away some day. 491 */ 492 ffs_oldfscompat(fs) 493 struct fs *fs; 494 { 495 int i; 496 497 fs->fs_npsect = max(fs->fs_npsect, fs->fs_nsect); /* XXX */ 498 fs->fs_interleave = max(fs->fs_interleave, 1); /* XXX */ 499 if (fs->fs_postblformat == FS_42POSTBLFMT) /* XXX */ 500 fs->fs_nrpos = 8; /* XXX */ 501 if (fs->fs_inodefmt < FS_44INODEFMT) { /* XXX */ 502 u_int64_t sizepb = fs->fs_bsize; /* XXX */ 503 /* XXX */ 504 fs->fs_maxfilesize = fs->fs_bsize * NDADDR - 1; /* XXX */ 505 for (i = 0; i < NIADDR; i++) { /* XXX */ 506 sizepb *= NINDIR(fs); /* XXX */ 507 fs->fs_maxfilesize += sizepb; /* XXX */ 508 } /* XXX */ 509 fs->fs_qbmask = ~fs->fs_bmask; /* XXX */ 510 fs->fs_qfmask = ~fs->fs_fmask; /* XXX */ 511 } /* XXX */ 512 return (0); 513 } 514 515 /* 516 * unmount system call 517 */ 518 int 519 ffs_unmount(mp, mntflags, p) 520 struct mount *mp; 521 int mntflags; 522 struct proc *p; 523 { 524 register struct ufsmount *ump; 525 register struct fs *fs; 526 int error, flags; 527 528 flags = 0; 529 if (mntflags & MNT_FORCE) 530 flags |= FORCECLOSE; 531 if (error = ffs_flushfiles(mp, flags, p)) 532 return (error); 533 ump = VFSTOUFS(mp); 534 fs = ump->um_fs; 535 if (fs->fs_ronly == 0) { 536 fs->fs_clean = 1; 537 if (error = ffs_sbupdate(ump, MNT_WAIT)) { 538 fs->fs_clean = 0; 539 return (error); 540 } 541 } 542 ump->um_devvp->v_specflags &= ~SI_MOUNTEDON; 543 error = VOP_CLOSE(ump->um_devvp, fs->fs_ronly ? FREAD : FREAD|FWRITE, 544 NOCRED, p); 545 vrele(ump->um_devvp); 546 free(fs->fs_csp[0], M_UFSMNT); 547 free(fs, M_UFSMNT); 548 free(ump, M_UFSMNT); 549 mp->mnt_data = (qaddr_t)0; 550 return (error); 551 } 552 553 /* 554 * Flush out all the files in a filesystem. 555 */ 556 ffs_flushfiles(mp, flags, p) 557 register struct mount *mp; 558 int flags; 559 struct proc *p; 560 { 561 register struct ufsmount *ump; 562 int i, error; 563 564 ump = VFSTOUFS(mp); 565 #ifdef QUOTA 566 if (mp->mnt_flag & MNT_QUOTA) { 567 if (error = vflush(mp, NULLVP, SKIPSYSTEM|flags)) 568 return (error); 569 for (i = 0; i < MAXQUOTAS; i++) { 570 if (ump->um_quotas[i] == NULLVP) 571 continue; 572 quotaoff(p, mp, i); 573 } 574 /* 575 * Here we fall through to vflush again to ensure 576 * that we have gotten rid of all the system vnodes. 577 */ 578 } 579 #endif 580 error = vflush(mp, NULLVP, flags); 581 return (error); 582 } 583 584 /* 585 * Get file system statistics. 586 */ 587 int 588 ffs_statfs(mp, sbp, p) 589 struct mount *mp; 590 register struct statfs *sbp; 591 struct proc *p; 592 { 593 register struct ufsmount *ump; 594 register struct fs *fs; 595 596 ump = VFSTOUFS(mp); 597 fs = ump->um_fs; 598 if (fs->fs_magic != FS_MAGIC) 599 panic("ffs_statfs"); 600 sbp->f_bsize = fs->fs_fsize; 601 sbp->f_iosize = fs->fs_bsize; 602 sbp->f_blocks = fs->fs_dsize; 603 sbp->f_bfree = fs->fs_cstotal.cs_nbfree * fs->fs_frag + 604 fs->fs_cstotal.cs_nffree; 605 sbp->f_bavail = (fs->fs_dsize * (100 - fs->fs_minfree) / 100) - 606 (fs->fs_dsize - sbp->f_bfree); 607 sbp->f_files = fs->fs_ncg * fs->fs_ipg - ROOTINO; 608 sbp->f_ffree = fs->fs_cstotal.cs_nifree; 609 if (sbp != &mp->mnt_stat) { 610 sbp->f_type = mp->mnt_vfc->vfc_typenum; 611 bcopy((caddr_t)mp->mnt_stat.f_mntonname, 612 (caddr_t)&sbp->f_mntonname[0], MNAMELEN); 613 bcopy((caddr_t)mp->mnt_stat.f_mntfromname, 614 (caddr_t)&sbp->f_mntfromname[0], MNAMELEN); 615 } 616 return (0); 617 } 618 619 /* 620 * Go through the disk queues to initiate sandbagged IO; 621 * go through the inodes to write those that have been modified; 622 * initiate the writing of the super block if it has been modified. 623 * 624 * Note: we are always called with the filesystem marked `MPBUSY'. 625 */ 626 int 627 ffs_sync(mp, waitfor, cred, p) 628 struct mount *mp; 629 int waitfor; 630 struct ucred *cred; 631 struct proc *p; 632 { 633 register struct vnode *vp; 634 register struct inode *ip; 635 register struct ufsmount *ump = VFSTOUFS(mp); 636 register struct fs *fs; 637 int error, allerror = 0; 638 639 fs = ump->um_fs; 640 if (fs->fs_fmod != 0 && fs->fs_ronly != 0) { /* XXX */ 641 printf("fs = %s\n", fs->fs_fsmnt); 642 panic("update: rofs mod"); 643 } 644 /* 645 * Write back each (modified) inode. 646 */ 647 loop: 648 for (vp = mp->mnt_vnodelist.lh_first; 649 vp != NULL; 650 vp = vp->v_mntvnodes.le_next) { 651 /* 652 * If the vnode that we are about to sync is no longer 653 * associated with this mount point, start over. 654 */ 655 if (vp->v_mount != mp) 656 goto loop; 657 if (VOP_ISLOCKED(vp)) 658 continue; 659 ip = VTOI(vp); 660 if ((ip->i_flag & 661 (IN_ACCESS | IN_CHANGE | IN_MODIFIED | IN_UPDATE)) == 0 && 662 vp->v_dirtyblkhd.lh_first == NULL) 663 continue; 664 if (vget(vp, 1)) 665 goto loop; 666 if (error = VOP_FSYNC(vp, cred, waitfor, p)) 667 allerror = error; 668 vput(vp); 669 } 670 /* 671 * Force stale file system control information to be flushed. 672 */ 673 if (error = VOP_FSYNC(ump->um_devvp, cred, waitfor, p)) 674 allerror = error; 675 #ifdef QUOTA 676 qsync(mp); 677 #endif 678 /* 679 * Write back modified superblock. 680 */ 681 if (fs->fs_fmod != 0) { 682 fs->fs_fmod = 0; 683 fs->fs_time = time.tv_sec; 684 if (error = ffs_sbupdate(ump, waitfor)) 685 allerror = error; 686 } 687 return (allerror); 688 } 689 690 /* 691 * Look up a FFS dinode number to find its incore vnode, otherwise read it 692 * in from disk. If it is in core, wait for the lock bit to clear, then 693 * return the inode locked. Detection and handling of mount points must be 694 * done by the calling routine. 695 */ 696 int 697 ffs_vget(mp, ino, vpp) 698 struct mount *mp; 699 ino_t ino; 700 struct vnode **vpp; 701 { 702 register struct fs *fs; 703 register struct inode *ip; 704 struct ufsmount *ump; 705 struct buf *bp; 706 struct vnode *vp; 707 dev_t dev; 708 int i, type, error; 709 710 ump = VFSTOUFS(mp); 711 dev = ump->um_dev; 712 if ((*vpp = ufs_ihashget(dev, ino)) != NULL) 713 return (0); 714 715 /* Allocate a new vnode/inode. */ 716 if (error = getnewvnode(VT_UFS, mp, ffs_vnodeop_p, &vp)) { 717 *vpp = NULL; 718 return (error); 719 } 720 type = ump->um_devvp->v_tag == VT_MFS ? M_MFSNODE : M_FFSNODE; /* XXX */ 721 MALLOC(ip, struct inode *, sizeof(struct inode), type, M_WAITOK); 722 bzero((caddr_t)ip, sizeof(struct inode)); 723 vp->v_data = ip; 724 ip->i_vnode = vp; 725 ip->i_fs = fs = ump->um_fs; 726 ip->i_dev = dev; 727 ip->i_number = ino; 728 #ifdef QUOTA 729 for (i = 0; i < MAXQUOTAS; i++) 730 ip->i_dquot[i] = NODQUOT; 731 #endif 732 /* 733 * Put it onto its hash chain and lock it so that other requests for 734 * this inode will block if they arrive while we are sleeping waiting 735 * for old data structures to be purged or for the contents of the 736 * disk portion of this inode to be read. 737 */ 738 ufs_ihashins(ip); 739 740 /* Read in the disk contents for the inode, copy into the inode. */ 741 if (error = bread(ump->um_devvp, fsbtodb(fs, ino_to_fsba(fs, ino)), 742 (int)fs->fs_bsize, NOCRED, &bp)) { 743 /* 744 * The inode does not contain anything useful, so it would 745 * be misleading to leave it on its hash chain. With mode 746 * still zero, it will be unlinked and returned to the free 747 * list by vput(). 748 */ 749 vput(vp); 750 brelse(bp); 751 *vpp = NULL; 752 return (error); 753 } 754 ip->i_din = *((struct dinode *)bp->b_data + ino_to_fsbo(fs, ino)); 755 brelse(bp); 756 757 /* 758 * Initialize the vnode from the inode, check for aliases. 759 * Note that the underlying vnode may have changed. 760 */ 761 if (error = ufs_vinit(mp, ffs_specop_p, FFS_FIFOOPS, &vp)) { 762 vput(vp); 763 *vpp = NULL; 764 return (error); 765 } 766 /* 767 * Finish inode initialization now that aliasing has been resolved. 768 */ 769 ip->i_devvp = ump->um_devvp; 770 VREF(ip->i_devvp); 771 /* 772 * Set up a generation number for this inode if it does not 773 * already have one. This should only happen on old filesystems. 774 */ 775 if (ip->i_gen == 0) { 776 if (++nextgennumber < (u_long)time.tv_sec) 777 nextgennumber = time.tv_sec; 778 ip->i_gen = nextgennumber; 779 if ((vp->v_mount->mnt_flag & MNT_RDONLY) == 0) 780 ip->i_flag |= IN_MODIFIED; 781 } 782 /* 783 * Ensure that uid and gid are correct. This is a temporary 784 * fix until fsck has been changed to do the update. 785 */ 786 if (fs->fs_inodefmt < FS_44INODEFMT) { /* XXX */ 787 ip->i_uid = ip->i_din.di_ouid; /* XXX */ 788 ip->i_gid = ip->i_din.di_ogid; /* XXX */ 789 } /* XXX */ 790 791 *vpp = vp; 792 return (0); 793 } 794 795 /* 796 * File handle to vnode 797 * 798 * Have to be really careful about stale file handles: 799 * - check that the inode number is valid 800 * - call ffs_vget() to get the locked inode 801 * - check for an unallocated inode (i_mode == 0) 802 * - check that the given client host has export rights and return 803 * those rights via. exflagsp and credanonp 804 */ 805 int 806 ffs_fhtovp(mp, fhp, nam, vpp, exflagsp, credanonp) 807 register struct mount *mp; 808 struct fid *fhp; 809 struct mbuf *nam; 810 struct vnode **vpp; 811 int *exflagsp; 812 struct ucred **credanonp; 813 { 814 register struct ufid *ufhp; 815 struct fs *fs; 816 817 ufhp = (struct ufid *)fhp; 818 fs = VFSTOUFS(mp)->um_fs; 819 if (ufhp->ufid_ino < ROOTINO || 820 ufhp->ufid_ino >= fs->fs_ncg * fs->fs_ipg) 821 return (ESTALE); 822 return (ufs_check_export(mp, ufhp, nam, vpp, exflagsp, credanonp)); 823 } 824 825 /* 826 * Vnode pointer to File handle 827 */ 828 /* ARGSUSED */ 829 ffs_vptofh(vp, fhp) 830 struct vnode *vp; 831 struct fid *fhp; 832 { 833 register struct inode *ip; 834 register struct ufid *ufhp; 835 836 ip = VTOI(vp); 837 ufhp = (struct ufid *)fhp; 838 ufhp->ufid_len = sizeof(struct ufid); 839 ufhp->ufid_ino = ip->i_number; 840 ufhp->ufid_gen = ip->i_gen; 841 return (0); 842 } 843 844 /* 845 * Initialize the filesystem; just use ufs_init. 846 */ 847 int 848 ffs_init(vfsp) 849 struct vfsconf *vfsp; 850 { 851 852 return (ufs_init(vfsp)); 853 } 854 855 /* 856 * fast filesystem related variables. 857 */ 858 ffs_sysctl(name, namelen, oldp, oldlenp, newp, newlen, p) 859 int *name; 860 u_int namelen; 861 void *oldp; 862 size_t *oldlenp; 863 void *newp; 864 size_t newlen; 865 struct proc *p; 866 { 867 extern int doclusterread, doclusterwrite, doreallocblks, doasyncfree; 868 869 /* all sysctl names at this level are terminal */ 870 if (namelen != 1) 871 return (ENOTDIR); /* overloaded */ 872 873 switch (name[0]) { 874 case FFS_CLUSTERREAD: 875 return (sysctl_int(oldp, oldlenp, newp, newlen, 876 &doclusterread)); 877 case FFS_CLUSTERWRITE: 878 return (sysctl_int(oldp, oldlenp, newp, newlen, 879 &doclusterwrite)); 880 case FFS_REALLOCBLKS: 881 return (sysctl_int(oldp, oldlenp, newp, newlen, 882 &doreallocblks)); 883 case FFS_ASYNCFREE: 884 return (sysctl_int(oldp, oldlenp, newp, newlen, &doasyncfree)); 885 default: 886 return (EOPNOTSUPP); 887 } 888 /* NOTREACHED */ 889 } 890 891 /* 892 * Write a superblock and associated information back to disk. 893 */ 894 int 895 ffs_sbupdate(mp, waitfor) 896 struct ufsmount *mp; 897 int waitfor; 898 { 899 register struct fs *dfs, *fs = mp->um_fs; 900 register struct buf *bp; 901 int blks; 902 caddr_t space; 903 int i, size, error, allerror = 0; 904 905 /* 906 * First write back the summary information. 907 */ 908 blks = howmany(fs->fs_cssize, fs->fs_fsize); 909 space = (caddr_t)fs->fs_csp[0]; 910 for (i = 0; i < blks; i += fs->fs_frag) { 911 size = fs->fs_bsize; 912 if (i + fs->fs_frag > blks) 913 size = (blks - i) * fs->fs_fsize; 914 bp = getblk(mp->um_devvp, fsbtodb(fs, fs->fs_csaddr + i), 915 size, 0, 0); 916 bcopy(space, bp->b_data, (u_int)size); 917 space += size; 918 if (waitfor != MNT_WAIT) 919 bawrite(bp); 920 else if (error = bwrite(bp)) 921 allerror = error; 922 } 923 /* 924 * Now write back the superblock itself. If any errors occurred 925 * up to this point, then fail so that the superblock avoids 926 * being written out as clean. 927 */ 928 if (allerror) 929 return (allerror); 930 bp = getblk(mp->um_devvp, SBLOCK, (int)fs->fs_sbsize, 0, 0); 931 bcopy((caddr_t)fs, bp->b_data, (u_int)fs->fs_sbsize); 932 /* Restore compatibility to old file systems. XXX */ 933 dfs = (struct fs *)bp->b_data; /* XXX */ 934 if (fs->fs_postblformat == FS_42POSTBLFMT) /* XXX */ 935 dfs->fs_nrpos = -1; /* XXX */ 936 if (fs->fs_inodefmt < FS_44INODEFMT) { /* XXX */ 937 int32_t *lp, tmp; /* XXX */ 938 /* XXX */ 939 lp = (int32_t *)&dfs->fs_qbmask; /* XXX */ 940 tmp = lp[4]; /* XXX */ 941 for (i = 4; i > 0; i--) /* XXX */ 942 lp[i] = lp[i-1]; /* XXX */ 943 lp[0] = tmp; /* XXX */ 944 } /* XXX */ 945 dfs->fs_maxfilesize = mp->um_savedmaxfilesize; /* XXX */ 946 if (waitfor != MNT_WAIT) 947 bawrite(bp); 948 else if (error = bwrite(bp)) 949 allerror = error; 950 return (allerror); 951 } 952