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