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