1 /* 2 * Copyright (c) 1989, 1991, 1993, 1994 3 * The Regents of the University of California. All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer. 10 * 2. Redistributions in binary form must reproduce the above copyright 11 * notice, this list of conditions and the following disclaimer in the 12 * documentation and/or other materials provided with the distribution. 13 * 3. All advertising materials mentioning features or use of this software 14 * must display the following acknowledgement: 15 * This product includes software developed by the University of 16 * California, Berkeley and its contributors. 17 * 4. Neither the name of the University nor the names of its contributors 18 * may be used to endorse or promote products derived from this software 19 * without specific prior written permission. 20 * 21 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 22 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 24 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 25 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 26 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 27 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 31 * SUCH DAMAGE. 32 * 33 * @(#)ffs_vfsops.c 8.8 (Berkeley) 4/18/94 34 * $Id: ffs_vfsops.c,v 1.19 1995/05/15 08:39:37 davidg Exp $ 35 */ 36 37 #include <sys/param.h> 38 #include <sys/systm.h> 39 #include <sys/namei.h> 40 #include <sys/proc.h> 41 #include <sys/kernel.h> 42 #include <sys/vnode.h> 43 #include <sys/socket.h> 44 #include <sys/mount.h> 45 #include <sys/buf.h> 46 #include <sys/mbuf.h> 47 #include <sys/file.h> 48 #include <sys/disklabel.h> 49 #include <sys/ioctl.h> 50 #include <sys/errno.h> 51 #include <sys/malloc.h> 52 53 #include <miscfs/specfs/specdev.h> 54 55 #include <ufs/ufs/quota.h> 56 #include <ufs/ufs/ufsmount.h> 57 #include <ufs/ufs/inode.h> 58 #include <ufs/ufs/ufs_extern.h> 59 60 #include <ufs/ffs/fs.h> 61 #include <ufs/ffs/ffs_extern.h> 62 63 #include <vm/vm.h> 64 #include <vm/vm_page.h> 65 #include <vm/vm_object.h> 66 67 int ffs_sbupdate __P((struct ufsmount *, int)); 68 int ffs_reload __P((struct mount *,struct ucred *,struct proc *)); 69 int ffs_oldfscompat __P((struct fs *)); 70 void ffs_vmlimits __P((struct fs *)); 71 72 struct vfsops ufs_vfsops = { 73 ffs_mount, 74 ufs_start, 75 ffs_unmount, 76 ufs_root, 77 ufs_quotactl, 78 ffs_statfs, 79 ffs_sync, 80 ffs_vget, 81 ffs_fhtovp, 82 ffs_vptofh, 83 ffs_init, 84 }; 85 86 VFS_SET(ufs_vfsops, ufs, MOUNT_UFS, 0); 87 88 extern u_long nextgennumber; 89 90 /* 91 * Called by main() when ufs is going to be mounted as root. 92 * 93 * Name is updated by mount(8) after booting. 94 */ 95 #define ROOTNAME "root_device" 96 97 int 98 ffs_mountroot() 99 { 100 register struct fs *fs; 101 register struct mount *mp; 102 struct proc *p = curproc; /* XXX */ 103 struct ufsmount *ump; 104 u_int size; 105 int error; 106 107 /* 108 * Get vnode for rootdev. 109 */ 110 if (bdevvp(rootdev, &rootvp)) 111 panic("ffs_mountroot: can't setup bdevvp for root"); 112 113 mp = malloc((u_long)sizeof(struct mount), M_MOUNT, M_WAITOK); 114 bzero((char *)mp, (u_long)sizeof(struct mount)); 115 mp->mnt_op = &ufs_vfsops; 116 mp->mnt_flag = MNT_RDONLY; 117 error = ffs_mountfs(rootvp, mp, p); 118 if (error) { 119 free(mp, M_MOUNT); 120 return (error); 121 } 122 error = vfs_lock(mp); 123 if (error) { 124 (void)ffs_unmount(mp, 0, p); 125 free(mp, M_MOUNT); 126 return (error); 127 } 128 TAILQ_INSERT_TAIL(&mountlist, mp, mnt_list); 129 mp->mnt_flag |= MNT_ROOTFS; 130 mp->mnt_vnodecovered = NULLVP; 131 ump = VFSTOUFS(mp); 132 fs = ump->um_fs; 133 bzero(fs->fs_fsmnt, sizeof(fs->fs_fsmnt)); 134 fs->fs_fsmnt[0] = '/'; 135 bcopy((caddr_t)fs->fs_fsmnt, (caddr_t)mp->mnt_stat.f_mntonname, 136 MNAMELEN); 137 (void) copystr(ROOTNAME, mp->mnt_stat.f_mntfromname, MNAMELEN - 1, 138 &size); 139 bzero(mp->mnt_stat.f_mntfromname + size, MNAMELEN - size); 140 (void)ffs_statfs(mp, &mp->mnt_stat, p); 141 vfs_unlock(mp); 142 inittodr(fs->fs_time); 143 return (0); 144 } 145 146 /* 147 * VFS Operations. 148 * 149 * mount system call 150 */ 151 int 152 ffs_mount(mp, path, data, ndp, p) 153 register struct mount *mp; 154 char *path; 155 caddr_t data; 156 struct nameidata *ndp; 157 struct proc *p; 158 { 159 struct vnode *devvp; 160 struct ufs_args args; 161 struct ufsmount *ump = 0; 162 register struct fs *fs; 163 u_int size; 164 int error, flags; 165 166 error = copyin(data, (caddr_t)&args, sizeof (struct ufs_args)); 167 if (error) 168 return (error); 169 /* 170 * If updating, check whether changing from read-only to 171 * read/write; if there is no device name, that's all we do. 172 */ 173 if (mp->mnt_flag & MNT_UPDATE) { 174 ump = VFSTOUFS(mp); 175 fs = ump->um_fs; 176 error = 0; 177 if (fs->fs_ronly == 0 && (mp->mnt_flag & MNT_RDONLY)) { 178 flags = WRITECLOSE; 179 if (mp->mnt_flag & MNT_FORCE) 180 flags |= FORCECLOSE; 181 if (vfs_busy(mp)) 182 return (EBUSY); 183 error = ffs_flushfiles(mp, flags, p); 184 vfs_unbusy(mp); 185 } 186 if (!error && (mp->mnt_flag & MNT_RELOAD)) 187 error = ffs_reload(mp, ndp->ni_cnd.cn_cred, p); 188 if (error) 189 return (error); 190 if (fs->fs_ronly && (mp->mnt_flag & MNT_WANTRDWR)) { 191 if (!fs->fs_clean) { 192 if (mp->mnt_flag & MNT_FORCE) { 193 printf("WARNING: %s was not properly dismounted.\n",fs->fs_fsmnt); 194 } else { 195 printf("WARNING: R/W mount of %s denied. Filesystem is not clean - run fsck.\n", 196 fs->fs_fsmnt); 197 return (EPERM); 198 } 199 } 200 fs->fs_ronly = 0; 201 } 202 if (fs->fs_ronly == 0) { 203 fs->fs_clean = 0; 204 ffs_sbupdate(ump, MNT_WAIT); 205 } 206 if (args.fspec == 0) { 207 /* 208 * Process export requests. 209 */ 210 return (vfs_export(mp, &ump->um_export, &args.export)); 211 } 212 } 213 /* 214 * Not an update, or updating the name: look up the name 215 * and verify that it refers to a sensible block device. 216 */ 217 NDINIT(ndp, LOOKUP, FOLLOW, UIO_USERSPACE, args.fspec, p); 218 error = namei(ndp); 219 if (error) 220 return (error); 221 devvp = ndp->ni_vp; 222 223 if (devvp->v_type != VBLK) { 224 vrele(devvp); 225 return (ENOTBLK); 226 } 227 if (major(devvp->v_rdev) >= nblkdev) { 228 vrele(devvp); 229 return (ENXIO); 230 } 231 if ((mp->mnt_flag & MNT_UPDATE) == 0) 232 error = ffs_mountfs(devvp, mp, p); 233 else { 234 if (devvp != ump->um_devvp) 235 error = EINVAL; /* needs translation */ 236 else 237 vrele(devvp); 238 } 239 if (error) { 240 vrele(devvp); 241 return (error); 242 } 243 ump = VFSTOUFS(mp); 244 fs = ump->um_fs; 245 (void) copyinstr(path, fs->fs_fsmnt, sizeof(fs->fs_fsmnt) - 1, &size); 246 bzero(fs->fs_fsmnt + size, sizeof(fs->fs_fsmnt) - size); 247 bcopy((caddr_t)fs->fs_fsmnt, (caddr_t)mp->mnt_stat.f_mntonname, 248 MNAMELEN); 249 (void) copyinstr(args.fspec, mp->mnt_stat.f_mntfromname, MNAMELEN - 1, 250 &size); 251 bzero(mp->mnt_stat.f_mntfromname + size, MNAMELEN - size); 252 (void)ffs_statfs(mp, &mp->mnt_stat, p); 253 return (0); 254 } 255 256 /* 257 * Reload all incore data for a filesystem (used after running fsck on 258 * the root filesystem and finding things to fix). The filesystem must 259 * be mounted read-only. 260 * 261 * Things to do to update the mount: 262 * 1) invalidate all cached meta-data. 263 * 2) re-read superblock from disk. 264 * 3) re-read summary information from disk. 265 * 4) invalidate all inactive vnodes. 266 * 5) invalidate all cached file data. 267 * 6) re-read inode data for all active vnodes. 268 */ 269 int 270 ffs_reload(mountp, cred, p) 271 register struct mount *mountp; 272 struct ucred *cred; 273 struct proc *p; 274 { 275 register struct vnode *vp, *nvp, *devvp; 276 struct inode *ip; 277 struct csum *space; 278 struct buf *bp; 279 struct fs *fs; 280 int i, blks, size, error; 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 error = bread(devvp, SBLOCK, SBSIZE, NOCRED, &bp); 294 if (error) 295 return (error); 296 fs = (struct fs *)bp->b_data; 297 if (fs->fs_magic != FS_MAGIC || fs->fs_bsize > MAXBSIZE || 298 fs->fs_bsize < sizeof(struct fs)) { 299 brelse(bp); 300 return (EIO); /* XXX needs translation */ 301 } 302 fs = VFSTOUFS(mountp)->um_fs; 303 bcopy(&fs->fs_csp[0], &((struct fs *)bp->b_data)->fs_csp[0], 304 sizeof(fs->fs_csp)); 305 bcopy(bp->b_data, fs, (u_int)fs->fs_sbsize); 306 if (fs->fs_sbsize < SBSIZE) 307 bp->b_flags |= B_INVAL; 308 brelse(bp); 309 ffs_oldfscompat(fs); 310 ffs_vmlimits(fs); 311 /* 312 * Step 3: re-read summary information from disk. 313 */ 314 blks = howmany(fs->fs_cssize, fs->fs_fsize); 315 space = fs->fs_csp[0]; 316 for (i = 0; i < blks; i += fs->fs_frag) { 317 size = fs->fs_bsize; 318 if (i + fs->fs_frag > blks) 319 size = (blks - i) * fs->fs_fsize; 320 error = bread(devvp, fsbtodb(fs, fs->fs_csaddr + i), size, 321 NOCRED, &bp); 322 if (error) 323 return (error); 324 bcopy(bp->b_data, fs->fs_csp[fragstoblks(fs, i)], (u_int)size); 325 brelse(bp); 326 } 327 loop: 328 for (vp = mountp->mnt_vnodelist.lh_first; vp != NULL; vp = nvp) { 329 nvp = vp->v_mntvnodes.le_next; 330 /* 331 * Step 4: invalidate all inactive vnodes. 332 */ 333 if (vp->v_usecount == 0) { 334 vgone(vp); 335 continue; 336 } 337 /* 338 * Step 5: invalidate all cached file data. 339 */ 340 if (vget(vp, 1)) 341 goto loop; 342 if (vinvalbuf(vp, 0, cred, p, 0, 0)) 343 panic("ffs_reload: dirty2"); 344 /* 345 * Step 6: re-read inode data for all active vnodes. 346 */ 347 ip = VTOI(vp); 348 error = 349 bread(devvp, fsbtodb(fs, ino_to_fsba(fs, ip->i_number)), 350 (int)fs->fs_bsize, NOCRED, &bp); 351 if (error) { 352 vput(vp); 353 return (error); 354 } 355 ip->i_din = *((struct dinode *)bp->b_data + 356 ino_to_fsbo(fs, ip->i_number)); 357 brelse(bp); 358 vput(vp); 359 if (vp->v_mount != mountp) 360 goto loop; 361 } 362 return (0); 363 } 364 365 /* 366 * Common code for mount and mountroot 367 */ 368 int 369 ffs_mountfs(devvp, mp, p) 370 register struct vnode *devvp; 371 struct mount *mp; 372 struct proc *p; 373 { 374 register struct ufsmount *ump; 375 struct buf *bp; 376 register struct fs *fs; 377 dev_t dev = devvp->v_rdev; 378 struct partinfo dpart; 379 caddr_t base, space; 380 int havepart = 0, blks; 381 int error, i, size; 382 int ronly; 383 384 /* 385 * Disallow multiple mounts of the same device. 386 * Disallow mounting of a device that is currently in use 387 * (except for root, which might share swap device for miniroot). 388 * Flush out any old buffers remaining from a previous use. 389 */ 390 error = vfs_mountedon(devvp); 391 if (error) 392 return (error); 393 if (vcount(devvp) > 1 && devvp != rootvp) 394 return (EBUSY); 395 error = vinvalbuf(devvp, V_SAVE, p->p_ucred, p, 0, 0); 396 if (error) 397 return (error); 398 399 ronly = (mp->mnt_flag & MNT_RDONLY) != 0; 400 error = VOP_OPEN(devvp, ronly ? FREAD : FREAD|FWRITE, FSCRED, p); 401 if (error) 402 return (error); 403 if (VOP_IOCTL(devvp, DIOCGPART, (caddr_t)&dpart, FREAD, NOCRED, p) != 0) 404 size = DEV_BSIZE; 405 else { 406 havepart = 1; 407 size = dpart.disklab->d_secsize; 408 } 409 410 bp = NULL; 411 ump = NULL; 412 error = bread(devvp, SBLOCK, SBSIZE, NOCRED, &bp); 413 if (error) 414 goto out; 415 fs = (struct fs *)bp->b_data; 416 if (fs->fs_magic != FS_MAGIC || fs->fs_bsize > MAXBSIZE || 417 fs->fs_bsize < sizeof(struct fs)) { 418 error = EINVAL; /* XXX needs translation */ 419 goto out; 420 } 421 if (!fs->fs_clean) { 422 if (ronly || (mp->mnt_flag & MNT_FORCE)) { 423 printf("WARNING: %s was not properly dismounted.\n",fs->fs_fsmnt); 424 } else { 425 printf("WARNING: R/W mount of %s denied. Filesystem is not clean - run fsck.\n",fs->fs_fsmnt); 426 error = EPERM; 427 goto out; 428 } 429 } 430 ump = malloc(sizeof *ump, M_UFSMNT, M_WAITOK); 431 bzero((caddr_t)ump, sizeof *ump); 432 ump->um_fs = malloc((u_long)fs->fs_sbsize, M_UFSMNT, 433 M_WAITOK); 434 bcopy(bp->b_data, ump->um_fs, (u_int)fs->fs_sbsize); 435 if (fs->fs_sbsize < SBSIZE) 436 bp->b_flags |= B_INVAL; 437 brelse(bp); 438 bp = NULL; 439 fs = ump->um_fs; 440 fs->fs_ronly = ronly; 441 if (ronly == 0) { 442 fs->fs_fmod = 1; 443 fs->fs_clean = 0; 444 } 445 blks = howmany(fs->fs_cssize, fs->fs_fsize); 446 base = space = malloc((u_long)fs->fs_cssize, M_UFSMNT, 447 M_WAITOK); 448 for (i = 0; i < blks; i += fs->fs_frag) { 449 size = fs->fs_bsize; 450 if (i + fs->fs_frag > blks) 451 size = (blks - i) * fs->fs_fsize; 452 error = bread(devvp, fsbtodb(fs, fs->fs_csaddr + i), size, 453 NOCRED, &bp); 454 if (error) { 455 free(base, M_UFSMNT); 456 goto out; 457 } 458 bcopy(bp->b_data, space, (u_int)size); 459 fs->fs_csp[fragstoblks(fs, i)] = (struct csum *)space; 460 space += size; 461 brelse(bp); 462 bp = NULL; 463 } 464 mp->mnt_data = (qaddr_t)ump; 465 mp->mnt_stat.f_fsid.val[0] = (long)dev; 466 mp->mnt_stat.f_fsid.val[1] = MOUNT_UFS; 467 mp->mnt_maxsymlinklen = fs->fs_maxsymlinklen; 468 mp->mnt_flag |= MNT_LOCAL; 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 ffs_vmlimits(fs); 480 if (ronly == 0) 481 ffs_sbupdate(ump, MNT_WAIT); 482 return (0); 483 out: 484 if (bp) 485 brelse(bp); 486 (void)VOP_CLOSE(devvp, ronly ? FREAD : FREAD|FWRITE, NOCRED, p); 487 if (ump) { 488 free(ump->um_fs, M_UFSMNT); 489 free(ump, M_UFSMNT); 490 mp->mnt_data = (qaddr_t)0; 491 } 492 return (error); 493 } 494 495 /* 496 * Sanity checks for old file systems. 497 * 498 * XXX - goes away some day. 499 */ 500 int 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 quad_t sizepb = fs->fs_bsize; /* XXX */ 512 /* XXX */ 513 #if 0 514 fs->fs_maxfilesize = fs->fs_bsize * NDADDR - 1; /* XXX */ 515 for (i = 0; i < NIADDR; i++) { /* XXX */ 516 sizepb *= NINDIR(fs); /* XXX */ 517 fs->fs_maxfilesize += sizepb; /* XXX */ 518 } /* XXX */ 519 #endif 520 fs->fs_maxfilesize = (u_quad_t) 1 << 39; 521 fs->fs_qbmask = ~fs->fs_bmask; /* XXX */ 522 fs->fs_qfmask = ~fs->fs_fmask; /* XXX */ 523 } /* XXX */ 524 return (0); 525 } 526 527 /* 528 * Sanity check for VM file size limits -- temporary until 529 * VM system can support > 32bit offsets 530 */ 531 void 532 ffs_vmlimits(fs) 533 struct fs *fs; 534 { 535 if( fs->fs_maxfilesize > (((u_quad_t) 1 << 31) - 1)) 536 fs->fs_maxfilesize = ((u_quad_t) 1 << 31) - 1; 537 } 538 539 /* 540 * unmount system call 541 */ 542 int 543 ffs_unmount(mp, mntflags, p) 544 struct mount *mp; 545 int mntflags; 546 struct proc *p; 547 { 548 register struct ufsmount *ump; 549 register struct fs *fs; 550 int error, flags, ronly; 551 552 flags = 0; 553 if (mntflags & MNT_FORCE) { 554 flags |= FORCECLOSE; 555 } 556 error = ffs_flushfiles(mp, flags, p); 557 if (error) 558 return (error); 559 ump = VFSTOUFS(mp); 560 fs = ump->um_fs; 561 ronly = fs->fs_ronly; 562 if (!ronly) { 563 fs->fs_clean = 1; 564 ffs_sbupdate(ump, MNT_WAIT); 565 } 566 ump->um_devvp->v_specflags &= ~SI_MOUNTEDON; 567 error = VOP_CLOSE(ump->um_devvp, ronly ? FREAD : FREAD|FWRITE, 568 NOCRED, p); 569 vrele(ump->um_devvp); 570 free(fs->fs_csp[0], M_UFSMNT); 571 free(fs, M_UFSMNT); 572 free(ump, M_UFSMNT); 573 mp->mnt_data = (qaddr_t)0; 574 mp->mnt_flag &= ~MNT_LOCAL; 575 return (error); 576 } 577 578 /* 579 * Flush out all the files in a filesystem. 580 */ 581 int 582 ffs_flushfiles(mp, flags, p) 583 register struct mount *mp; 584 int flags; 585 struct proc *p; 586 { 587 register struct ufsmount *ump; 588 int error; 589 590 if (!doforce) 591 flags &= ~FORCECLOSE; 592 ump = VFSTOUFS(mp); 593 #ifdef QUOTA 594 if (mp->mnt_flag & MNT_QUOTA) { 595 int i; 596 error = vflush(mp, NULLVP, SKIPSYSTEM|flags); 597 if (error) 598 return (error); 599 for (i = 0; i < MAXQUOTAS; i++) { 600 if (ump->um_quotas[i] == NULLVP) 601 continue; 602 quotaoff(p, mp, i); 603 } 604 /* 605 * Here we fall through to vflush again to ensure 606 * that we have gotten rid of all the system vnodes. 607 */ 608 } 609 #endif 610 error = vflush(mp, NULLVP, flags); 611 return (error); 612 } 613 614 /* 615 * Get file system statistics. 616 */ 617 int 618 ffs_statfs(mp, sbp, p) 619 struct mount *mp; 620 register struct statfs *sbp; 621 struct proc *p; 622 { 623 register struct ufsmount *ump; 624 register struct fs *fs; 625 626 ump = VFSTOUFS(mp); 627 fs = ump->um_fs; 628 if (fs->fs_magic != FS_MAGIC) 629 panic("ffs_statfs"); 630 sbp->f_type = MOUNT_UFS; 631 sbp->f_bsize = fs->fs_fsize; 632 sbp->f_iosize = fs->fs_bsize; 633 sbp->f_blocks = fs->fs_dsize; 634 sbp->f_bfree = fs->fs_cstotal.cs_nbfree * fs->fs_frag + 635 fs->fs_cstotal.cs_nffree; 636 sbp->f_bavail = (fs->fs_dsize * (100 - fs->fs_minfree) / 100) - 637 (fs->fs_dsize - sbp->f_bfree); 638 sbp->f_files = fs->fs_ncg * fs->fs_ipg - ROOTINO; 639 sbp->f_ffree = fs->fs_cstotal.cs_nifree; 640 if (sbp != &mp->mnt_stat) { 641 bcopy((caddr_t)mp->mnt_stat.f_mntonname, 642 (caddr_t)&sbp->f_mntonname[0], MNAMELEN); 643 bcopy((caddr_t)mp->mnt_stat.f_mntfromname, 644 (caddr_t)&sbp->f_mntfromname[0], MNAMELEN); 645 } 646 return (0); 647 } 648 649 /* 650 * Go through the disk queues to initiate sandbagged IO; 651 * go through the inodes to write those that have been modified; 652 * initiate the writing of the super block if it has been modified. 653 * 654 * Note: we are always called with the filesystem marked `MPBUSY'. 655 */ 656 int 657 ffs_sync(mp, waitfor, cred, p) 658 struct mount *mp; 659 int waitfor; 660 struct ucred *cred; 661 struct proc *p; 662 { 663 register struct vnode *vp; 664 register struct inode *ip; 665 register struct ufsmount *ump = VFSTOUFS(mp); 666 register struct fs *fs; 667 struct timeval tv; 668 int error, allerror = 0; 669 670 fs = ump->um_fs; 671 /* 672 * Write back modified superblock. 673 * Consistency check that the superblock 674 * is still in the buffer cache. 675 */ 676 if (fs->fs_fmod != 0) { 677 if (fs->fs_ronly != 0) { /* XXX */ 678 printf("fs = %s\n", fs->fs_fsmnt); 679 panic("update: rofs mod"); 680 } 681 fs->fs_fmod = 0; 682 fs->fs_time = time.tv_sec; 683 allerror = ffs_sbupdate(ump, waitfor); 684 } 685 /* 686 * Write back each (modified) inode. 687 */ 688 loop: 689 for (vp = mp->mnt_vnodelist.lh_first; 690 vp != NULL; 691 vp = vp->v_mntvnodes.le_next) { 692 /* 693 * If the vnode that we are about to sync is no longer 694 * associated with this mount point, start over. 695 */ 696 if (vp->v_mount != mp) 697 goto loop; 698 if (VOP_ISLOCKED(vp)) 699 continue; 700 ip = VTOI(vp); 701 if (vp->v_vmdata && 702 (((vm_object_t) vp->v_vmdata)->flags & OBJ_WRITEABLE)) { 703 if (vget(vp, 1)) 704 goto loop; 705 _vm_object_page_clean( (vm_object_t) vp->v_vmdata, 706 0, 0, 0); 707 vput(vp); 708 } 709 710 if ((((ip->i_flag & 711 (IN_ACCESS | IN_CHANGE | IN_MODIFIED | IN_UPDATE)) == 0)) && 712 vp->v_dirtyblkhd.lh_first == NULL) 713 continue; 714 if (vp->v_type != VCHR) { 715 if (vget(vp, 1)) 716 goto loop; 717 error = VOP_FSYNC(vp, cred, waitfor, p); 718 if (error) 719 allerror = error; 720 vput(vp); 721 } else { 722 tv = time; 723 VOP_UPDATE(vp, &tv, &tv, waitfor == MNT_WAIT); 724 } 725 } 726 /* 727 * Force stale file system control information to be flushed. 728 */ 729 error = VOP_FSYNC(ump->um_devvp, cred, waitfor, p); 730 if (error) 731 allerror = error; 732 #ifdef QUOTA 733 qsync(mp); 734 #endif 735 return (allerror); 736 } 737 738 /* 739 * Look up a FFS dinode number to find its incore vnode, otherwise read it 740 * in from disk. If it is in core, wait for the lock bit to clear, then 741 * return the inode locked. Detection and handling of mount points must be 742 * done by the calling routine. 743 */ 744 int 745 ffs_vget(mp, ino, vpp) 746 struct mount *mp; 747 ino_t ino; 748 struct vnode **vpp; 749 { 750 register struct fs *fs; 751 register struct inode *ip; 752 struct ufsmount *ump; 753 struct buf *bp; 754 struct vnode *vp; 755 dev_t dev; 756 int type, error; 757 758 ump = VFSTOUFS(mp); 759 dev = ump->um_dev; 760 if ((*vpp = ufs_ihashget(dev, ino)) != NULL) 761 return (0); 762 763 /* Allocate a new vnode/inode. */ 764 error = getnewvnode(VT_UFS, mp, ffs_vnodeop_p, &vp); 765 if (error) { 766 *vpp = NULL; 767 return (error); 768 } 769 type = ump->um_devvp->v_tag == VT_MFS ? M_MFSNODE : M_FFSNODE; /* XXX */ 770 MALLOC(ip, struct inode *, sizeof(struct inode), type, M_WAITOK); 771 bzero((caddr_t)ip, sizeof(struct inode)); 772 vp->v_data = ip; 773 ip->i_vnode = vp; 774 ip->i_fs = fs = ump->um_fs; 775 ip->i_dev = dev; 776 ip->i_number = ino; 777 #ifdef QUOTA 778 { 779 int i; 780 for (i = 0; i < MAXQUOTAS; i++) 781 ip->i_dquot[i] = NODQUOT; 782 } 783 #endif 784 /* 785 * Put it onto its hash chain and lock it so that other requests for 786 * this inode will block if they arrive while we are sleeping waiting 787 * for old data structures to be purged or for the contents of the 788 * disk portion of this inode to be read. 789 */ 790 ufs_ihashins(ip); 791 792 /* Read in the disk contents for the inode, copy into the inode. */ 793 error = bread(ump->um_devvp, fsbtodb(fs, ino_to_fsba(fs, ino)), 794 (int)fs->fs_bsize, NOCRED, &bp); 795 if (error) { 796 /* 797 * The inode does not contain anything useful, so it would 798 * be misleading to leave it on its hash chain. With mode 799 * still zero, it will be unlinked and returned to the free 800 * list by vput(). 801 */ 802 vput(vp); 803 brelse(bp); 804 *vpp = NULL; 805 return (error); 806 } 807 ip->i_din = *((struct dinode *)bp->b_data + ino_to_fsbo(fs, ino)); 808 brelse(bp); 809 810 /* 811 * Initialize the vnode from the inode, check for aliases. 812 * Note that the underlying vnode may have changed. 813 */ 814 error = ufs_vinit(mp, ffs_specop_p, FFS_FIFOOPS, &vp); 815 if (error) { 816 vput(vp); 817 *vpp = NULL; 818 return (error); 819 } 820 /* 821 * Finish inode initialization now that aliasing has been resolved. 822 */ 823 ip->i_devvp = ump->um_devvp; 824 VREF(ip->i_devvp); 825 /* 826 * Set up a generation number for this inode if it does not 827 * already have one. This should only happen on old filesystems. 828 */ 829 if (ip->i_gen == 0) { 830 if (++nextgennumber < (u_long)time.tv_sec) 831 nextgennumber = time.tv_sec; 832 ip->i_gen = nextgennumber; 833 if ((vp->v_mount->mnt_flag & MNT_RDONLY) == 0) 834 ip->i_flag |= IN_MODIFIED; 835 } 836 /* 837 * Ensure that uid and gid are correct. This is a temporary 838 * fix until fsck has been changed to do the update. 839 */ 840 if (fs->fs_inodefmt < FS_44INODEFMT) { /* XXX */ 841 ip->i_uid = ip->i_din.di_ouid; /* XXX */ 842 ip->i_gid = ip->i_din.di_ogid; /* XXX */ 843 } /* XXX */ 844 845 *vpp = vp; 846 return (0); 847 } 848 849 /* 850 * File handle to vnode 851 * 852 * Have to be really careful about stale file handles: 853 * - check that the inode number is valid 854 * - call ffs_vget() to get the locked inode 855 * - check for an unallocated inode (i_mode == 0) 856 * - check that the given client host has export rights and return 857 * those rights via. exflagsp and credanonp 858 */ 859 int 860 ffs_fhtovp(mp, fhp, nam, vpp, exflagsp, credanonp) 861 register struct mount *mp; 862 struct fid *fhp; 863 struct mbuf *nam; 864 struct vnode **vpp; 865 int *exflagsp; 866 struct ucred **credanonp; 867 { 868 register struct ufid *ufhp; 869 struct fs *fs; 870 871 ufhp = (struct ufid *)fhp; 872 fs = VFSTOUFS(mp)->um_fs; 873 if (ufhp->ufid_ino < ROOTINO || 874 ufhp->ufid_ino >= fs->fs_ncg * fs->fs_ipg) 875 return (ESTALE); 876 return (ufs_check_export(mp, ufhp, nam, vpp, exflagsp, credanonp)); 877 } 878 879 /* 880 * Vnode pointer to File handle 881 */ 882 /* ARGSUSED */ 883 int 884 ffs_vptofh(vp, fhp) 885 struct vnode *vp; 886 struct fid *fhp; 887 { 888 register struct inode *ip; 889 register struct ufid *ufhp; 890 891 ip = VTOI(vp); 892 ufhp = (struct ufid *)fhp; 893 ufhp->ufid_len = sizeof(struct ufid); 894 ufhp->ufid_ino = ip->i_number; 895 ufhp->ufid_gen = ip->i_gen; 896 return (0); 897 } 898 899 /* 900 * Write a superblock and associated information back to disk. 901 */ 902 int 903 ffs_sbupdate(mp, waitfor) 904 struct ufsmount *mp; 905 int waitfor; 906 { 907 register struct fs *fs = mp->um_fs; 908 register struct buf *bp; 909 int blks; 910 caddr_t space; 911 int i, size, error = 0; 912 913 bp = getblk(mp->um_devvp, SBLOCK, (int)fs->fs_sbsize, 0, 0); 914 bcopy((caddr_t)fs, bp->b_data, (u_int)fs->fs_sbsize); 915 /* Restore compatibility to old file systems. XXX */ 916 if (fs->fs_postblformat == FS_42POSTBLFMT) /* XXX */ 917 ((struct fs *)bp->b_data)->fs_nrpos = -1; /* XXX */ 918 if (waitfor == MNT_WAIT) 919 error = bwrite(bp); 920 else 921 bawrite(bp); 922 blks = howmany(fs->fs_cssize, fs->fs_fsize); 923 space = (caddr_t)fs->fs_csp[0]; 924 for (i = 0; i < blks; i += fs->fs_frag) { 925 size = fs->fs_bsize; 926 if (i + fs->fs_frag > blks) 927 size = (blks - i) * fs->fs_fsize; 928 bp = getblk(mp->um_devvp, fsbtodb(fs, fs->fs_csaddr + i), 929 size, 0, 0); 930 bcopy(space, bp->b_data, (u_int)size); 931 space += size; 932 if (waitfor == MNT_WAIT) 933 error = bwrite(bp); 934 else 935 bawrite(bp); 936 } 937 return (error); 938 } 939