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