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