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.28 (Berkeley) 05/14/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 vn_lock(devvp, LK_EXCLUSIVE | LK_RETRY, p); 160 if (error = VOP_ACCESS(devvp, VREAD | VWRITE, 161 p->p_ucred, p)) { 162 VOP_UNLOCK(devvp, 0, p); 163 return (error); 164 } 165 VOP_UNLOCK(devvp, 0, p); 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 vn_lock(devvp, LK_EXCLUSIVE | LK_RETRY, p); 204 if (error = VOP_ACCESS(devvp, accessmode, p->p_ucred, p)) { 205 vput(devvp); 206 return (error); 207 } 208 VOP_UNLOCK(devvp, 0, p); 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 323 loop: 324 simple_lock(&mntvnode_slock); 325 for (vp = mountp->mnt_vnodelist.lh_first; vp != NULL; vp = nvp) { 326 if (vp->v_mount != mountp) { 327 simple_unlock(&mntvnode_slock); 328 goto loop; 329 } 330 nvp = vp->v_mntvnodes.le_next; 331 /* 332 * Step 4: invalidate all inactive vnodes. 333 */ 334 if (vrecycle(vp, &mntvnode_slock, p)) 335 goto loop; 336 /* 337 * Step 5: invalidate all cached file data. 338 */ 339 simple_lock(&vp->v_interlock); 340 simple_unlock(&mntvnode_slock); 341 if (vget(vp, LK_EXCLUSIVE | LK_INTERLOCK, p)) { 342 goto loop; 343 } 344 if (vinvalbuf(vp, 0, cred, p, 0, 0)) 345 panic("ffs_reload: dirty2"); 346 /* 347 * Step 6: re-read inode data for all active vnodes. 348 */ 349 ip = VTOI(vp); 350 if (error = 351 bread(devvp, fsbtodb(fs, ino_to_fsba(fs, ip->i_number)), 352 (int)fs->fs_bsize, NOCRED, &bp)) { 353 vput(vp); 354 return (error); 355 } 356 ip->i_din = *((struct dinode *)bp->b_data + 357 ino_to_fsbo(fs, ip->i_number)); 358 brelse(bp); 359 vput(vp); 360 simple_lock(&mntvnode_slock); 361 } 362 simple_unlock(&mntvnode_slock); 363 return (0); 364 } 365 366 /* 367 * Common code for mount and mountroot 368 */ 369 int 370 ffs_mountfs(devvp, mp, p) 371 register struct vnode *devvp; 372 struct mount *mp; 373 struct proc *p; 374 { 375 register struct ufsmount *ump; 376 struct buf *bp; 377 register struct fs *fs; 378 dev_t dev; 379 struct partinfo dpart; 380 caddr_t base, space; 381 int error, i, blks, size, ronly; 382 int32_t *lp; 383 struct ucred *cred; 384 extern struct vnode *rootvp; 385 u_int64_t maxfilesize; /* XXX */ 386 387 dev = devvp->v_rdev; 388 cred = p ? p->p_ucred : NOCRED; 389 /* 390 * Disallow multiple mounts of the same device. 391 * Disallow mounting of a device that is currently in use 392 * (except for root, which might share swap device for miniroot). 393 * Flush out any old buffers remaining from a previous use. 394 */ 395 if (error = vfs_mountedon(devvp)) 396 return (error); 397 if (vcount(devvp) > 1 && devvp != rootvp) 398 return (EBUSY); 399 if (error = vinvalbuf(devvp, V_SAVE, cred, p, 0, 0)) 400 return (error); 401 402 ronly = (mp->mnt_flag & MNT_RDONLY) != 0; 403 if (error = VOP_OPEN(devvp, ronly ? FREAD : FREAD|FWRITE, FSCRED, p)) 404 return (error); 405 if (VOP_IOCTL(devvp, DIOCGPART, (caddr_t)&dpart, FREAD, cred, p) != 0) 406 size = DEV_BSIZE; 407 else 408 size = dpart.disklab->d_secsize; 409 410 bp = NULL; 411 ump = NULL; 412 if (error = bread(devvp, (ufs_daddr_t)(SBOFF/size), SBSIZE, cred, &bp)) 413 goto out; 414 fs = (struct fs *)bp->b_data; 415 if (fs->fs_magic != FS_MAGIC || fs->fs_bsize > MAXBSIZE || 416 fs->fs_bsize < sizeof(struct fs)) { 417 error = EINVAL; /* XXX needs translation */ 418 goto out; 419 } 420 /* XXX updating 4.2 FFS superblocks trashes rotational layout tables */ 421 if (fs->fs_postblformat == FS_42POSTBLFMT && !ronly) { 422 error = EROFS; /* needs translation */ 423 goto out; 424 } 425 ump = malloc(sizeof *ump, M_UFSMNT, M_WAITOK); 426 bzero((caddr_t)ump, sizeof *ump); 427 ump->um_fs = malloc((u_long)fs->fs_sbsize, M_UFSMNT, 428 M_WAITOK); 429 bcopy(bp->b_data, ump->um_fs, (u_int)fs->fs_sbsize); 430 if (fs->fs_sbsize < SBSIZE) 431 bp->b_flags |= B_INVAL; 432 brelse(bp); 433 bp = NULL; 434 fs = ump->um_fs; 435 fs->fs_ronly = ronly; 436 size = fs->fs_cssize; 437 blks = howmany(size, fs->fs_fsize); 438 if (fs->fs_contigsumsize > 0) 439 size += fs->fs_ncg * sizeof(int32_t); 440 base = space = malloc((u_long)size, M_UFSMNT, M_WAITOK); 441 for (i = 0; i < blks; i += fs->fs_frag) { 442 size = fs->fs_bsize; 443 if (i + fs->fs_frag > blks) 444 size = (blks - i) * fs->fs_fsize; 445 if (error = bread(devvp, fsbtodb(fs, fs->fs_csaddr + i), size, 446 cred, &bp)) { 447 free(base, M_UFSMNT); 448 goto out; 449 } 450 bcopy(bp->b_data, space, (u_int)size); 451 fs->fs_csp[fragstoblks(fs, i)] = (struct csum *)space; 452 space += size; 453 brelse(bp); 454 bp = NULL; 455 } 456 if (fs->fs_contigsumsize > 0) { 457 fs->fs_maxcluster = lp = (int32_t *)space; 458 for (i = 0; i < fs->fs_ncg; i++) 459 *lp++ = fs->fs_contigsumsize; 460 } 461 mp->mnt_data = (qaddr_t)ump; 462 mp->mnt_stat.f_fsid.val[0] = (long)dev; 463 mp->mnt_stat.f_fsid.val[1] = mp->mnt_vfc->vfc_typenum; 464 mp->mnt_maxsymlinklen = fs->fs_maxsymlinklen; 465 ump->um_mountp = mp; 466 ump->um_dev = dev; 467 ump->um_devvp = devvp; 468 ump->um_nindir = fs->fs_nindir; 469 ump->um_bptrtodb = fs->fs_fsbtodb; 470 ump->um_seqinc = fs->fs_frag; 471 for (i = 0; i < MAXQUOTAS; i++) 472 ump->um_quotas[i] = NULLVP; 473 devvp->v_specflags |= SI_MOUNTEDON; 474 ffs_oldfscompat(fs); 475 ump->um_savedmaxfilesize = fs->fs_maxfilesize; /* XXX */ 476 maxfilesize = (u_int64_t)0x40000000 * fs->fs_bsize - 1; /* XXX */ 477 if (fs->fs_maxfilesize > maxfilesize) /* XXX */ 478 fs->fs_maxfilesize = maxfilesize; /* XXX */ 479 if (ronly == 0) { 480 fs->fs_clean = 0; 481 (void) ffs_sbupdate(ump, MNT_WAIT); 482 } 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 flags |= FORCECLOSE; 540 if (error = ffs_flushfiles(mp, flags, p)) 541 return (error); 542 ump = VFSTOUFS(mp); 543 fs = ump->um_fs; 544 if (fs->fs_ronly == 0) { 545 fs->fs_clean = 1; 546 if (error = ffs_sbupdate(ump, MNT_WAIT)) { 547 fs->fs_clean = 0; 548 return (error); 549 } 550 } 551 ump->um_devvp->v_specflags &= ~SI_MOUNTEDON; 552 error = VOP_CLOSE(ump->um_devvp, fs->fs_ronly ? FREAD : FREAD|FWRITE, 553 NOCRED, p); 554 vrele(ump->um_devvp); 555 free(fs->fs_csp[0], M_UFSMNT); 556 free(fs, M_UFSMNT); 557 free(ump, M_UFSMNT); 558 mp->mnt_data = (qaddr_t)0; 559 return (error); 560 } 561 562 /* 563 * Flush out all the files in a filesystem. 564 */ 565 ffs_flushfiles(mp, flags, p) 566 register struct mount *mp; 567 int flags; 568 struct proc *p; 569 { 570 register struct ufsmount *ump; 571 int i, error; 572 573 ump = VFSTOUFS(mp); 574 #ifdef QUOTA 575 if (mp->mnt_flag & MNT_QUOTA) { 576 if (error = vflush(mp, NULLVP, SKIPSYSTEM|flags)) 577 return (error); 578 for (i = 0; i < MAXQUOTAS; i++) { 579 if (ump->um_quotas[i] == NULLVP) 580 continue; 581 quotaoff(p, mp, i); 582 } 583 /* 584 * Here we fall through to vflush again to ensure 585 * that we have gotten rid of all the system vnodes. 586 */ 587 } 588 #endif 589 error = vflush(mp, NULLVP, flags); 590 return (error); 591 } 592 593 /* 594 * Get file system statistics. 595 */ 596 int 597 ffs_statfs(mp, sbp, p) 598 struct mount *mp; 599 register struct statfs *sbp; 600 struct proc *p; 601 { 602 register struct ufsmount *ump; 603 register struct fs *fs; 604 605 ump = VFSTOUFS(mp); 606 fs = ump->um_fs; 607 if (fs->fs_magic != FS_MAGIC) 608 panic("ffs_statfs"); 609 sbp->f_bsize = fs->fs_fsize; 610 sbp->f_iosize = fs->fs_bsize; 611 sbp->f_blocks = fs->fs_dsize; 612 sbp->f_bfree = fs->fs_cstotal.cs_nbfree * fs->fs_frag + 613 fs->fs_cstotal.cs_nffree; 614 sbp->f_bavail = (fs->fs_dsize * (100 - fs->fs_minfree) / 100) - 615 (fs->fs_dsize - sbp->f_bfree); 616 sbp->f_files = fs->fs_ncg * fs->fs_ipg - ROOTINO; 617 sbp->f_ffree = fs->fs_cstotal.cs_nifree; 618 if (sbp != &mp->mnt_stat) { 619 sbp->f_type = mp->mnt_vfc->vfc_typenum; 620 bcopy((caddr_t)mp->mnt_stat.f_mntonname, 621 (caddr_t)&sbp->f_mntonname[0], MNAMELEN); 622 bcopy((caddr_t)mp->mnt_stat.f_mntfromname, 623 (caddr_t)&sbp->f_mntfromname[0], MNAMELEN); 624 } 625 return (0); 626 } 627 628 /* 629 * Go through the disk queues to initiate sandbagged IO; 630 * go through the inodes to write those that have been modified; 631 * initiate the writing of the super block if it has been modified. 632 * 633 * Note: we are always called with the filesystem marked `MPBUSY'. 634 */ 635 int 636 ffs_sync(mp, waitfor, cred, p) 637 struct mount *mp; 638 int waitfor; 639 struct ucred *cred; 640 struct proc *p; 641 { 642 struct vnode *nvp, *vp; 643 struct inode *ip; 644 struct ufsmount *ump = VFSTOUFS(mp); 645 struct fs *fs; 646 int error, allerror = 0; 647 648 fs = ump->um_fs; 649 if (fs->fs_fmod != 0 && fs->fs_ronly != 0) { /* XXX */ 650 printf("fs = %s\n", fs->fs_fsmnt); 651 panic("update: rofs mod"); 652 } 653 /* 654 * Write back each (modified) inode. 655 */ 656 simple_lock(&mntvnode_slock); 657 loop: 658 for (vp = mp->mnt_vnodelist.lh_first; 659 vp != NULL; 660 vp = nvp) { 661 /* 662 * If the vnode that we are about to sync is no longer 663 * associated with this mount point, start over. 664 */ 665 if (vp->v_mount != mp) 666 goto loop; 667 simple_lock(&vp->v_interlock); 668 nvp = vp->v_mntvnodes.le_next; 669 ip = VTOI(vp); 670 if ((ip->i_flag & 671 (IN_ACCESS | IN_CHANGE | IN_MODIFIED | IN_UPDATE)) == 0 && 672 vp->v_dirtyblkhd.lh_first == NULL) { 673 simple_unlock(&vp->v_interlock); 674 continue; 675 } 676 simple_unlock(&mntvnode_slock); 677 error = vget(vp, LK_EXCLUSIVE | LK_NOWAIT | LK_INTERLOCK, p); 678 if (error) { 679 simple_lock(&mntvnode_slock); 680 if (error == ENOENT) 681 goto loop; 682 continue; 683 } 684 if (error = VOP_FSYNC(vp, cred, waitfor, p)) 685 allerror = error; 686 VOP_UNLOCK(vp, 0, p); 687 vrele(vp); 688 simple_lock(&mntvnode_slock); 689 } 690 simple_unlock(&mntvnode_slock); 691 /* 692 * Force stale file system control information to be flushed. 693 */ 694 if (error = VOP_FSYNC(ump->um_devvp, cred, waitfor, p)) 695 allerror = error; 696 #ifdef QUOTA 697 qsync(mp); 698 #endif 699 /* 700 * Write back modified superblock. 701 */ 702 if (fs->fs_fmod != 0) { 703 fs->fs_fmod = 0; 704 fs->fs_time = time.tv_sec; 705 if (error = ffs_sbupdate(ump, waitfor)) 706 allerror = error; 707 } 708 return (allerror); 709 } 710 711 /* 712 * Look up a FFS dinode number to find its incore vnode, otherwise read it 713 * in from disk. If it is in core, wait for the lock bit to clear, then 714 * return the inode locked. Detection and handling of mount points must be 715 * done by the calling routine. 716 */ 717 int 718 ffs_vget(mp, ino, vpp) 719 struct mount *mp; 720 ino_t ino; 721 struct vnode **vpp; 722 { 723 struct proc *p = curproc; /* XXX */ 724 struct fs *fs; 725 struct inode *ip; 726 struct ufsmount *ump; 727 struct buf *bp; 728 struct vnode *vp; 729 dev_t dev; 730 int i, type, error; 731 732 ump = VFSTOUFS(mp); 733 dev = ump->um_dev; 734 if ((*vpp = ufs_ihashget(dev, ino)) != NULL) 735 return (0); 736 737 /* Allocate a new vnode/inode. */ 738 if (error = getnewvnode(VT_UFS, mp, ffs_vnodeop_p, &vp)) { 739 *vpp = NULL; 740 return (error); 741 } 742 type = ump->um_devvp->v_tag == VT_MFS ? M_MFSNODE : M_FFSNODE; /* XXX */ 743 MALLOC(ip, struct inode *, sizeof(struct inode), type, M_WAITOK); 744 bzero((caddr_t)ip, sizeof(struct inode)); 745 #ifdef DEBUG 746 /* 747 * Set two second timeout, after which die assuming a hung lock. 748 */ 749 lockinit(&ip->i_lock, PINOD, "inode", 200, 0); 750 #else 751 lockinit(&ip->i_lock, PINOD, "inode", 0, 0); 752 #endif 753 vp->v_data = ip; 754 ip->i_vnode = vp; 755 ip->i_fs = fs = ump->um_fs; 756 ip->i_dev = dev; 757 ip->i_number = ino; 758 #ifdef QUOTA 759 for (i = 0; i < MAXQUOTAS; i++) 760 ip->i_dquot[i] = NODQUOT; 761 #endif 762 /* 763 * Put it onto its hash chain and lock it so that other requests for 764 * this inode will block if they arrive while we are sleeping waiting 765 * for old data structures to be purged or for the contents of the 766 * disk portion of this inode to be read. 767 */ 768 ufs_ihashins(ip); 769 770 /* Read in the disk contents for the inode, copy into the inode. */ 771 if (error = bread(ump->um_devvp, fsbtodb(fs, ino_to_fsba(fs, ino)), 772 (int)fs->fs_bsize, NOCRED, &bp)) { 773 /* 774 * The inode does not contain anything useful, so it would 775 * be misleading to leave it on its hash chain. With mode 776 * still zero, it will be unlinked and returned to the free 777 * list by vput(). 778 */ 779 vput(vp); 780 brelse(bp); 781 *vpp = NULL; 782 return (error); 783 } 784 ip->i_din = *((struct dinode *)bp->b_data + ino_to_fsbo(fs, ino)); 785 brelse(bp); 786 787 /* 788 * Initialize the vnode from the inode, check for aliases. 789 * Note that the underlying vnode may have changed. 790 */ 791 if (error = ufs_vinit(mp, ffs_specop_p, FFS_FIFOOPS, &vp)) { 792 vput(vp); 793 *vpp = NULL; 794 return (error); 795 } 796 /* 797 * Finish inode initialization now that aliasing has been resolved. 798 */ 799 ip->i_devvp = ump->um_devvp; 800 VREF(ip->i_devvp); 801 /* 802 * Set up a generation number for this inode if it does not 803 * already have one. This should only happen on old filesystems. 804 */ 805 if (ip->i_gen == 0) { 806 if (++nextgennumber < (u_long)time.tv_sec) 807 nextgennumber = time.tv_sec; 808 ip->i_gen = nextgennumber; 809 if ((vp->v_mount->mnt_flag & MNT_RDONLY) == 0) 810 ip->i_flag |= IN_MODIFIED; 811 } 812 /* 813 * Ensure that uid and gid are correct. This is a temporary 814 * fix until fsck has been changed to do the update. 815 */ 816 if (fs->fs_inodefmt < FS_44INODEFMT) { /* XXX */ 817 ip->i_uid = ip->i_din.di_ouid; /* XXX */ 818 ip->i_gid = ip->i_din.di_ogid; /* XXX */ 819 } /* XXX */ 820 821 *vpp = vp; 822 return (0); 823 } 824 825 /* 826 * File handle to vnode 827 * 828 * Have to be really careful about stale file handles: 829 * - check that the inode number is valid 830 * - call ffs_vget() to get the locked inode 831 * - check for an unallocated inode (i_mode == 0) 832 * - check that the given client host has export rights and return 833 * those rights via. exflagsp and credanonp 834 */ 835 int 836 ffs_fhtovp(mp, fhp, nam, vpp, exflagsp, credanonp) 837 register struct mount *mp; 838 struct fid *fhp; 839 struct mbuf *nam; 840 struct vnode **vpp; 841 int *exflagsp; 842 struct ucred **credanonp; 843 { 844 register struct ufid *ufhp; 845 struct fs *fs; 846 847 ufhp = (struct ufid *)fhp; 848 fs = VFSTOUFS(mp)->um_fs; 849 if (ufhp->ufid_ino < ROOTINO || 850 ufhp->ufid_ino >= fs->fs_ncg * fs->fs_ipg) 851 return (ESTALE); 852 return (ufs_check_export(mp, ufhp, nam, vpp, exflagsp, credanonp)); 853 } 854 855 /* 856 * Vnode pointer to File handle 857 */ 858 /* ARGSUSED */ 859 ffs_vptofh(vp, fhp) 860 struct vnode *vp; 861 struct fid *fhp; 862 { 863 register struct inode *ip; 864 register struct ufid *ufhp; 865 866 ip = VTOI(vp); 867 ufhp = (struct ufid *)fhp; 868 ufhp->ufid_len = sizeof(struct ufid); 869 ufhp->ufid_ino = ip->i_number; 870 ufhp->ufid_gen = ip->i_gen; 871 return (0); 872 } 873 874 /* 875 * Initialize the filesystem; just use ufs_init. 876 */ 877 int 878 ffs_init(vfsp) 879 struct vfsconf *vfsp; 880 { 881 882 return (ufs_init(vfsp)); 883 } 884 885 /* 886 * fast filesystem related variables. 887 */ 888 ffs_sysctl(name, namelen, oldp, oldlenp, newp, newlen, p) 889 int *name; 890 u_int namelen; 891 void *oldp; 892 size_t *oldlenp; 893 void *newp; 894 size_t newlen; 895 struct proc *p; 896 { 897 extern int doclusterread, doclusterwrite, doreallocblks, doasyncfree; 898 899 /* all sysctl names at this level are terminal */ 900 if (namelen != 1) 901 return (ENOTDIR); /* overloaded */ 902 903 switch (name[0]) { 904 case FFS_CLUSTERREAD: 905 return (sysctl_int(oldp, oldlenp, newp, newlen, 906 &doclusterread)); 907 case FFS_CLUSTERWRITE: 908 return (sysctl_int(oldp, oldlenp, newp, newlen, 909 &doclusterwrite)); 910 case FFS_REALLOCBLKS: 911 return (sysctl_int(oldp, oldlenp, newp, newlen, 912 &doreallocblks)); 913 case FFS_ASYNCFREE: 914 return (sysctl_int(oldp, oldlenp, newp, newlen, &doasyncfree)); 915 default: 916 return (EOPNOTSUPP); 917 } 918 /* NOTREACHED */ 919 } 920 921 /* 922 * Write a superblock and associated information back to disk. 923 */ 924 int 925 ffs_sbupdate(mp, waitfor) 926 struct ufsmount *mp; 927 int waitfor; 928 { 929 register struct fs *dfs, *fs = mp->um_fs; 930 register struct buf *bp; 931 int blks; 932 caddr_t space; 933 int i, size, error, allerror = 0; 934 935 /* 936 * First write back the summary information. 937 */ 938 blks = howmany(fs->fs_cssize, fs->fs_fsize); 939 space = (caddr_t)fs->fs_csp[0]; 940 for (i = 0; i < blks; i += fs->fs_frag) { 941 size = fs->fs_bsize; 942 if (i + fs->fs_frag > blks) 943 size = (blks - i) * fs->fs_fsize; 944 bp = getblk(mp->um_devvp, fsbtodb(fs, fs->fs_csaddr + i), 945 size, 0, 0); 946 bcopy(space, bp->b_data, (u_int)size); 947 space += size; 948 if (waitfor != MNT_WAIT) 949 bawrite(bp); 950 else if (error = bwrite(bp)) 951 allerror = error; 952 } 953 /* 954 * Now write back the superblock itself. If any errors occurred 955 * up to this point, then fail so that the superblock avoids 956 * being written out as clean. 957 */ 958 if (allerror) 959 return (allerror); 960 bp = getblk(mp->um_devvp, SBLOCK, (int)fs->fs_sbsize, 0, 0); 961 bcopy((caddr_t)fs, bp->b_data, (u_int)fs->fs_sbsize); 962 /* Restore compatibility to old file systems. XXX */ 963 dfs = (struct fs *)bp->b_data; /* XXX */ 964 if (fs->fs_postblformat == FS_42POSTBLFMT) /* XXX */ 965 dfs->fs_nrpos = -1; /* XXX */ 966 if (fs->fs_inodefmt < FS_44INODEFMT) { /* XXX */ 967 int32_t *lp, tmp; /* XXX */ 968 /* XXX */ 969 lp = (int32_t *)&dfs->fs_qbmask; /* XXX */ 970 tmp = lp[4]; /* XXX */ 971 for (i = 4; i > 0; i--) /* XXX */ 972 lp[i] = lp[i-1]; /* XXX */ 973 lp[0] = tmp; /* XXX */ 974 } /* XXX */ 975 dfs->fs_maxfilesize = mp->um_savedmaxfilesize; /* XXX */ 976 if (waitfor != MNT_WAIT) 977 bawrite(bp); 978 else if (error = bwrite(bp)) 979 allerror = error; 980 return (allerror); 981 } 982