ffs_vfsops.c revision 33108
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.31 (Berkeley) 5/20/95 34 * $Id: ffs_vfsops.c,v 1.68 1998/02/01 08:23:58 dyson Exp $ 35 */ 36 37#include "opt_diagnostic.h" 38#include "opt_quota.h" 39 40#include <sys/param.h> 41#include <sys/systm.h> 42#include <sys/namei.h> 43#include <sys/proc.h> 44#include <sys/kernel.h> 45#include <sys/vnode.h> 46#include <sys/mount.h> 47#include <sys/buf.h> 48#include <sys/conf.h> 49#include <sys/fcntl.h> 50#include <sys/disklabel.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_prot.h> 65#include <vm/vm_page.h> 66#include <vm/vm_extern.h> 67#include <vm/vm_object.h> 68 69static MALLOC_DEFINE(M_FFSNODE, "FFS node", "FFS vnode private part"); 70 71static int ffs_sbupdate __P((struct ufsmount *, int)); 72static int ffs_reload __P((struct mount *,struct ucred *,struct proc *)); 73static int ffs_oldfscompat __P((struct fs *)); 74static int ffs_mount __P((struct mount *, char *, caddr_t, 75 struct nameidata *, struct proc *)); 76static int ffs_init __P((struct vfsconf *)); 77 78struct vfsops ufs_vfsops = { 79 ffs_mount, 80 ufs_start, 81 ffs_unmount, 82 ufs_root, 83 ufs_quotactl, 84 ffs_statfs, 85 ffs_sync, 86 ffs_vget, 87 ffs_fhtovp, 88 ffs_vptofh, 89 ffs_init, 90}; 91 92VFS_SET(ufs_vfsops, ufs, MOUNT_UFS, 0); 93 94/* 95 * ffs_mount 96 * 97 * Called when mounting local physical media 98 * 99 * PARAMETERS: 100 * mountroot 101 * mp mount point structure 102 * path NULL (flag for root mount!!!) 103 * data <unused> 104 * ndp <unused> 105 * p process (user credentials check [statfs]) 106 * 107 * mount 108 * mp mount point structure 109 * path path to mount point 110 * data pointer to argument struct in user space 111 * ndp mount point namei() return (used for 112 * credentials on reload), reused to look 113 * up block device. 114 * p process (user credentials check) 115 * 116 * RETURNS: 0 Success 117 * !0 error number (errno.h) 118 * 119 * LOCK STATE: 120 * 121 * ENTRY 122 * mount point is locked 123 * EXIT 124 * mount point is locked 125 * 126 * NOTES: 127 * A NULL path can be used for a flag since the mount 128 * system call will fail with EFAULT in copyinstr in 129 * namei() if it is a genuine NULL from the user. 130 */ 131static int 132ffs_mount( mp, path, data, ndp, p) 133 struct mount *mp; /* mount struct pointer*/ 134 char *path; /* path to mount point*/ 135 caddr_t data; /* arguments to FS specific mount*/ 136 struct nameidata *ndp; /* mount point credentials*/ 137 struct proc *p; /* process requesting mount*/ 138{ 139 u_int size; 140 int err = 0; 141 struct vnode *devvp; 142 143 struct ufs_args args; 144 struct ufsmount *ump = 0; 145 register struct fs *fs; 146 int flags; 147 148 /* 149 * Use NULL path to flag a root mount 150 */ 151 if( path == NULL) { 152 /* 153 *** 154 * Mounting root file system 155 *** 156 */ 157 158 if ((err = bdevvp(rootdev, &rootvp))) { 159 printf("ffs_mountroot: can't find rootvp"); 160 return (err); 161 } 162 163 if (bdevsw[major(rootdev)]->d_flags & D_NOCLUSTERR) 164 mp->mnt_flag |= MNT_NOCLUSTERR; 165 if (bdevsw[major(rootdev)]->d_flags & D_NOCLUSTERW) 166 mp->mnt_flag |= MNT_NOCLUSTERW; 167 if( ( err = ffs_mountfs(rootvp, mp, p, M_FFSNODE)) != 0) { 168 /* fs specific cleanup (if any)*/ 169 goto error_1; 170 } 171 172 goto dostatfs; /* success*/ 173 174 } 175 176 /* 177 *** 178 * Mounting non-root file system or updating a file system 179 *** 180 */ 181 182 /* copy in user arguments*/ 183 err = copyin(data, (caddr_t)&args, sizeof (struct ufs_args)); 184 if (err) 185 goto error_1; /* can't get arguments*/ 186 187 /* 188 * If updating, check whether changing from read-only to 189 * read/write; if there is no device name, that's all we do. 190 * Disallow clearing MNT_NOCLUSTERR and MNT_NOCLUSTERW flags, 191 * if block device requests. 192 */ 193 if (mp->mnt_flag & MNT_UPDATE) { 194 ump = VFSTOUFS(mp); 195 fs = ump->um_fs; 196 err = 0; 197 if (bdevsw[major(ump->um_dev)]->d_flags & D_NOCLUSTERR) 198 mp->mnt_flag |= MNT_NOCLUSTERR; 199 if (bdevsw[major(ump->um_dev)]->d_flags & D_NOCLUSTERW) 200 mp->mnt_flag |= MNT_NOCLUSTERW; 201 if (fs->fs_ronly == 0 && (mp->mnt_flag & MNT_RDONLY)) { 202 flags = WRITECLOSE; 203 if (mp->mnt_flag & MNT_FORCE) 204 flags |= FORCECLOSE; 205 err = ffs_flushfiles(mp, flags, p); 206 } 207 if (!err && (mp->mnt_flag & MNT_RELOAD)) 208 err = ffs_reload(mp, ndp->ni_cnd.cn_cred, p); 209 if (err) { 210 goto error_1; 211 } 212 if (fs->fs_ronly && (mp->mnt_kern_flag & MNTK_WANTRDWR)) { 213 if (!fs->fs_clean) { 214 if (mp->mnt_flag & MNT_FORCE) { 215 printf("WARNING: %s was not properly dismounted.\n",fs->fs_fsmnt); 216 } else { 217 printf("WARNING: R/W mount of %s denied. Filesystem is not clean - run fsck.\n", 218 fs->fs_fsmnt); 219 err = EPERM; 220 goto error_1; 221 } 222 } 223 fs->fs_ronly = 0; 224 } 225 if (fs->fs_ronly == 0) { 226 fs->fs_clean = 0; 227 ffs_sbupdate(ump, MNT_WAIT); 228 } 229 /* if not updating name...*/ 230 if (args.fspec == 0) { 231 /* 232 * Process export requests. Jumping to "success" 233 * will return the vfs_export() error code. 234 */ 235 err = vfs_export(mp, &ump->um_export, &args.export); 236 goto success; 237 } 238 } 239 240 /* 241 * Not an update, or updating the name: look up the name 242 * and verify that it refers to a sensible block device. 243 */ 244 NDINIT(ndp, LOOKUP, FOLLOW, UIO_USERSPACE, args.fspec, p); 245 err = namei(ndp); 246 if (err) { 247 /* can't get devvp!*/ 248 goto error_1; 249 } 250 251 devvp = ndp->ni_vp; 252 253 if (devvp->v_type != VBLK) { 254 err = ENOTBLK; 255 goto error_2; 256 } 257 if (major(devvp->v_rdev) >= nblkdev) { 258 err = ENXIO; 259 goto error_2; 260 } 261 if (mp->mnt_flag & MNT_UPDATE) { 262 /* 263 ******************** 264 * UPDATE 265 ******************** 266 */ 267 268 if (devvp != ump->um_devvp) 269 err = EINVAL; /* needs translation */ 270 else 271 vrele(devvp); 272 /* 273 * Update device name only on success 274 */ 275 if( !err) { 276 /* Save "mounted from" info for mount point (NULL pad)*/ 277 copyinstr( args.fspec, 278 mp->mnt_stat.f_mntfromname, 279 MNAMELEN - 1, 280 &size); 281 bzero( mp->mnt_stat.f_mntfromname + size, MNAMELEN - size); 282 } 283 } else { 284 /* 285 ******************** 286 * NEW MOUNT 287 ******************** 288 */ 289 290 if (bdevsw[major(devvp->v_rdev)]->d_flags & D_NOCLUSTERR) 291 mp->mnt_flag |= MNT_NOCLUSTERR; 292 if (bdevsw[major(devvp->v_rdev)]->d_flags & D_NOCLUSTERW) 293 mp->mnt_flag |= MNT_NOCLUSTERW; 294 295 /* 296 * Since this is a new mount, we want the names for 297 * the device and the mount point copied in. If an 298 * error occurs, the mountpoint is discarded by the 299 * upper level code. 300 */ 301 /* Save "last mounted on" info for mount point (NULL pad)*/ 302 copyinstr( path, /* mount point*/ 303 mp->mnt_stat.f_mntonname, /* save area*/ 304 MNAMELEN - 1, /* max size*/ 305 &size); /* real size*/ 306 bzero( mp->mnt_stat.f_mntonname + size, MNAMELEN - size); 307 308 /* Save "mounted from" info for mount point (NULL pad)*/ 309 copyinstr( args.fspec, /* device name*/ 310 mp->mnt_stat.f_mntfromname, /* save area*/ 311 MNAMELEN - 1, /* max size*/ 312 &size); /* real size*/ 313 bzero( mp->mnt_stat.f_mntfromname + size, MNAMELEN - size); 314 315 err = ffs_mountfs(devvp, mp, p, M_FFSNODE); 316 } 317 if (err) { 318 goto error_2; 319 } 320 321dostatfs: 322 /* 323 * Initialize FS stat information in mount struct; uses both 324 * mp->mnt_stat.f_mntonname and mp->mnt_stat.f_mntfromname 325 * 326 * This code is common to root and non-root mounts 327 */ 328 (void)VFS_STATFS(mp, &mp->mnt_stat, p); 329 330 goto success; 331 332 333error_2: /* error with devvp held*/ 334 335 /* release devvp before failing*/ 336 vrele(devvp); 337 338error_1: /* no state to back out*/ 339 340success: 341 return( err); 342} 343 344/* 345 * Reload all incore data for a filesystem (used after running fsck on 346 * the root filesystem and finding things to fix). The filesystem must 347 * be mounted read-only. 348 * 349 * Things to do to update the mount: 350 * 1) invalidate all cached meta-data. 351 * 2) re-read superblock from disk. 352 * 3) re-read summary information from disk. 353 * 4) invalidate all inactive vnodes. 354 * 5) invalidate all cached file data. 355 * 6) re-read inode data for all active vnodes. 356 */ 357static int 358ffs_reload(mp, cred, p) 359 register struct mount *mp; 360 struct ucred *cred; 361 struct proc *p; 362{ 363 register struct vnode *vp, *nvp, *devvp; 364 struct inode *ip; 365 struct csum *space; 366 struct buf *bp; 367 struct fs *fs, *newfs; 368 struct partinfo dpart; 369 dev_t dev; 370 int i, blks, size, error; 371 int32_t *lp; 372 373 if ((mp->mnt_flag & MNT_RDONLY) == 0) 374 return (EINVAL); 375 /* 376 * Step 1: invalidate all cached meta-data. 377 */ 378 devvp = VFSTOUFS(mp)->um_devvp; 379 if (vinvalbuf(devvp, 0, cred, p, 0, 0)) 380 panic("ffs_reload: dirty1"); 381 382 dev = devvp->v_rdev; 383 /* 384 * Only VMIO the backing device if the backing device is a real 385 * block device. This excludes the original MFS implementation. 386 * Note that it is optional that the backing device be VMIOed. This 387 * increases the opportunity for metadata caching. 388 */ 389 if ((devvp->v_type == VBLK) && (major(dev) < nblkdev)) { 390 simple_lock(&devvp->v_interlock); 391 vfs_object_create(devvp, p, p->p_ucred, 0); 392 } 393 394 /* 395 * Step 2: re-read superblock from disk. 396 */ 397 if (VOP_IOCTL(devvp, DIOCGPART, (caddr_t)&dpart, FREAD, NOCRED, p) != 0) 398 size = DEV_BSIZE; 399 else 400 size = dpart.disklab->d_secsize; 401 if (error = bread(devvp, (ufs_daddr_t)(SBOFF/size), SBSIZE, NOCRED,&bp)) 402 return (error); 403 newfs = (struct fs *)bp->b_data; 404 if (newfs->fs_magic != FS_MAGIC || newfs->fs_bsize > MAXBSIZE || 405 newfs->fs_bsize < sizeof(struct fs)) { 406 brelse(bp); 407 return (EIO); /* XXX needs translation */ 408 } 409 fs = VFSTOUFS(mp)->um_fs; 410 /* 411 * Copy pointer fields back into superblock before copying in XXX 412 * new superblock. These should really be in the ufsmount. XXX 413 * Note that important parameters (eg fs_ncg) are unchanged. 414 */ 415 bcopy(&fs->fs_csp[0], &newfs->fs_csp[0], sizeof(fs->fs_csp)); 416 newfs->fs_maxcluster = fs->fs_maxcluster; 417 bcopy(newfs, fs, (u_int)fs->fs_sbsize); 418 if (fs->fs_sbsize < SBSIZE) 419 bp->b_flags |= B_INVAL; 420 brelse(bp); 421 mp->mnt_maxsymlinklen = fs->fs_maxsymlinklen; 422 ffs_oldfscompat(fs); 423 424 /* 425 * Step 3: re-read summary information from disk. 426 */ 427 blks = howmany(fs->fs_cssize, fs->fs_fsize); 428 space = fs->fs_csp[0]; 429 for (i = 0; i < blks; i += fs->fs_frag) { 430 size = fs->fs_bsize; 431 if (i + fs->fs_frag > blks) 432 size = (blks - i) * fs->fs_fsize; 433 error = bread(devvp, fsbtodb(fs, fs->fs_csaddr + i), size, 434 NOCRED, &bp); 435 if (error) 436 return (error); 437 bcopy(bp->b_data, fs->fs_csp[fragstoblks(fs, i)], (u_int)size); 438 brelse(bp); 439 } 440 /* 441 * We no longer know anything about clusters per cylinder group. 442 */ 443 if (fs->fs_contigsumsize > 0) { 444 lp = fs->fs_maxcluster; 445 for (i = 0; i < fs->fs_ncg; i++) 446 *lp++ = fs->fs_contigsumsize; 447 } 448 449loop: 450 simple_lock(&mntvnode_slock); 451 for (vp = mp->mnt_vnodelist.lh_first; vp != NULL; vp = nvp) { 452 if (vp->v_mount != mp) { 453 simple_unlock(&mntvnode_slock); 454 goto loop; 455 } 456 nvp = vp->v_mntvnodes.le_next; 457 /* 458 * Step 4: invalidate all inactive vnodes. 459 */ 460 if (vrecycle(vp, &mntvnode_slock, p)) 461 goto loop; 462 /* 463 * Step 5: invalidate all cached file data. 464 */ 465 simple_lock(&vp->v_interlock); 466 simple_unlock(&mntvnode_slock); 467 if (vget(vp, LK_EXCLUSIVE | LK_INTERLOCK, p)) { 468 goto loop; 469 } 470 if (vinvalbuf(vp, 0, cred, p, 0, 0)) 471 panic("ffs_reload: dirty2"); 472 /* 473 * Step 6: re-read inode data for all active vnodes. 474 */ 475 ip = VTOI(vp); 476 error = 477 bread(devvp, fsbtodb(fs, ino_to_fsba(fs, ip->i_number)), 478 (int)fs->fs_bsize, NOCRED, &bp); 479 if (error) { 480 vput(vp); 481 return (error); 482 } 483 ip->i_din = *((struct dinode *)bp->b_data + 484 ino_to_fsbo(fs, ip->i_number)); 485 brelse(bp); 486 vput(vp); 487 simple_lock(&mntvnode_slock); 488 } 489 simple_unlock(&mntvnode_slock); 490 return (0); 491} 492 493/* 494 * Common code for mount and mountroot 495 */ 496int 497ffs_mountfs(devvp, mp, p, malloctype) 498 register struct vnode *devvp; 499 struct mount *mp; 500 struct proc *p; 501 struct malloc_type *malloctype; 502{ 503 register struct ufsmount *ump; 504 struct buf *bp; 505 register struct fs *fs; 506 dev_t dev; 507 struct partinfo dpart; 508 caddr_t base, space; 509 int error, i, blks, size, ronly; 510 int32_t *lp; 511 struct ucred *cred; 512 u_int64_t maxfilesize; /* XXX */ 513 u_int strsize; 514 int ncount; 515 516 dev = devvp->v_rdev; 517 cred = p ? p->p_ucred : NOCRED; 518 /* 519 * Disallow multiple mounts of the same device. 520 * Disallow mounting of a device that is currently in use 521 * (except for root, which might share swap device for miniroot). 522 * Flush out any old buffers remaining from a previous use. 523 */ 524 error = vfs_mountedon(devvp); 525 if (error) 526 return (error); 527 ncount = vcount(devvp); 528/* 529 if (devvp->v_object) 530 ncount -= 1; 531*/ 532 if (ncount > 1 && devvp != rootvp) 533 return (EBUSY); 534 if (error = vinvalbuf(devvp, V_SAVE, cred, p, 0, 0)) 535 return (error); 536 537 /* 538 * Only VMIO the backing device if the backing device is a real 539 * block device. This excludes the original MFS implementation. 540 * Note that it is optional that the backing device be VMIOed. This 541 * increases the opportunity for metadata caching. 542 */ 543 if ((devvp->v_type == VBLK) && (major(dev) < nblkdev)) { 544 vfs_object_create(devvp, p, p->p_ucred, 0); 545 } 546 547 548 ronly = (mp->mnt_flag & MNT_RDONLY) != 0; 549 error = VOP_OPEN(devvp, ronly ? FREAD : FREAD|FWRITE, FSCRED, p); 550 if (error) 551 return (error); 552 553 if (VOP_IOCTL(devvp, DIOCGPART, (caddr_t)&dpart, FREAD, cred, p) != 0) 554 size = DEV_BSIZE; 555 else 556 size = dpart.disklab->d_secsize; 557 558 bp = NULL; 559 ump = NULL; 560 if (error = bread(devvp, SBLOCK, SBSIZE, cred, &bp)) 561 goto out; 562 fs = (struct fs *)bp->b_data; 563 if (fs->fs_magic != FS_MAGIC || fs->fs_bsize > MAXBSIZE || 564 fs->fs_bsize < sizeof(struct fs)) { 565 error = EINVAL; /* XXX needs translation */ 566 goto out; 567 } 568 fs->fs_fmod = 0; 569 if (!fs->fs_clean) { 570 if (ronly || (mp->mnt_flag & MNT_FORCE)) { 571 printf("WARNING: %s was not properly dismounted.\n",fs->fs_fsmnt); 572 } else { 573 printf("WARNING: R/W mount of %s denied. Filesystem is not clean - run fsck.\n",fs->fs_fsmnt); 574 error = EPERM; 575 goto out; 576 } 577 } 578 /* XXX updating 4.2 FFS superblocks trashes rotational layout tables */ 579 if (fs->fs_postblformat == FS_42POSTBLFMT && !ronly) { 580 error = EROFS; /* needs translation */ 581 goto out; 582 } 583 ump = malloc(sizeof *ump, M_UFSMNT, M_WAITOK); 584 bzero((caddr_t)ump, sizeof *ump); 585 ump->um_malloctype = malloctype; 586 ump->um_fs = malloc((u_long)fs->fs_sbsize, M_UFSMNT, 587 M_WAITOK); 588 ump->um_blkatoff = ffs_blkatoff; 589 ump->um_truncate = ffs_truncate; 590 ump->um_update = ffs_update; 591 ump->um_valloc = ffs_valloc; 592 ump->um_vfree = ffs_vfree; 593 bcopy(bp->b_data, ump->um_fs, (u_int)fs->fs_sbsize); 594 if (fs->fs_sbsize < SBSIZE) 595 bp->b_flags |= B_INVAL; 596 brelse(bp); 597 bp = NULL; 598 fs = ump->um_fs; 599 fs->fs_ronly = ronly; 600 if (ronly == 0) { 601 fs->fs_fmod = 1; 602 fs->fs_clean = 0; 603 } 604 size = fs->fs_cssize; 605 blks = howmany(size, fs->fs_fsize); 606 if (fs->fs_contigsumsize > 0) 607 size += fs->fs_ncg * sizeof(int32_t); 608 base = space = malloc((u_long)size, M_UFSMNT, M_WAITOK); 609 for (i = 0; i < blks; i += fs->fs_frag) { 610 size = fs->fs_bsize; 611 if (i + fs->fs_frag > blks) 612 size = (blks - i) * fs->fs_fsize; 613 if (error = bread(devvp, fsbtodb(fs, fs->fs_csaddr + i), size, 614 cred, &bp)) { 615 free(base, M_UFSMNT); 616 goto out; 617 } 618 bcopy(bp->b_data, space, (u_int)size); 619 fs->fs_csp[fragstoblks(fs, i)] = (struct csum *)space; 620 space += size; 621 brelse(bp); 622 bp = NULL; 623 } 624 if (fs->fs_contigsumsize > 0) { 625 fs->fs_maxcluster = lp = (int32_t *)space; 626 for (i = 0; i < fs->fs_ncg; i++) 627 *lp++ = fs->fs_contigsumsize; 628 } 629 mp->mnt_data = (qaddr_t)ump; 630 mp->mnt_stat.f_fsid.val[0] = (long)dev; 631 if (fs->fs_id[0] != 0 && fs->fs_id[1] != 0) 632 mp->mnt_stat.f_fsid.val[1] = fs->fs_id[1]; 633 else 634 mp->mnt_stat.f_fsid.val[1] = mp->mnt_vfc->vfc_typenum; 635 mp->mnt_maxsymlinklen = fs->fs_maxsymlinklen; 636 mp->mnt_flag |= MNT_LOCAL; 637 ump->um_mountp = mp; 638 ump->um_dev = dev; 639 ump->um_devvp = devvp; 640 ump->um_nindir = fs->fs_nindir; 641 ump->um_bptrtodb = fs->fs_fsbtodb; 642 ump->um_seqinc = fs->fs_frag; 643 for (i = 0; i < MAXQUOTAS; i++) 644 ump->um_quotas[i] = NULLVP; 645 devvp->v_specflags |= SI_MOUNTEDON; 646 ffs_oldfscompat(fs); 647 648 /* 649 * Set FS local "last mounted on" information (NULL pad) 650 */ 651 copystr( mp->mnt_stat.f_mntonname, /* mount point*/ 652 fs->fs_fsmnt, /* copy area*/ 653 sizeof(fs->fs_fsmnt) - 1, /* max size*/ 654 &strsize); /* real size*/ 655 bzero( fs->fs_fsmnt + strsize, sizeof(fs->fs_fsmnt) - strsize); 656 657 if( mp->mnt_flag & MNT_ROOTFS) { 658 /* 659 * Root mount; update timestamp in mount structure. 660 * this will be used by the common root mount code 661 * to update the system clock. 662 */ 663 mp->mnt_time = fs->fs_time; 664 } 665 666 ump->um_savedmaxfilesize = fs->fs_maxfilesize; /* XXX */ 667 maxfilesize = (u_int64_t)0x40000000 * fs->fs_bsize - 1; /* XXX */ 668 if (fs->fs_maxfilesize > maxfilesize) /* XXX */ 669 fs->fs_maxfilesize = maxfilesize; /* XXX */ 670 if (ronly == 0) { 671 fs->fs_clean = 0; 672 (void) ffs_sbupdate(ump, MNT_WAIT); 673 } 674 return (0); 675out: 676 if (bp) 677 brelse(bp); 678 (void)VOP_CLOSE(devvp, ronly ? FREAD : FREAD|FWRITE, cred, p); 679 if (ump) { 680 free(ump->um_fs, M_UFSMNT); 681 free(ump, M_UFSMNT); 682 mp->mnt_data = (qaddr_t)0; 683 } 684 return (error); 685} 686 687/* 688 * Sanity checks for old file systems. 689 * 690 * XXX - goes away some day. 691 */ 692static int 693ffs_oldfscompat(fs) 694 struct fs *fs; 695{ 696 697 fs->fs_npsect = max(fs->fs_npsect, fs->fs_nsect); /* XXX */ 698 fs->fs_interleave = max(fs->fs_interleave, 1); /* XXX */ 699 if (fs->fs_postblformat == FS_42POSTBLFMT) /* XXX */ 700 fs->fs_nrpos = 8; /* XXX */ 701 if (fs->fs_inodefmt < FS_44INODEFMT) { /* XXX */ 702#if 0 703 int i; /* XXX */ 704 u_int64_t sizepb = fs->fs_bsize; /* XXX */ 705 /* XXX */ 706 fs->fs_maxfilesize = fs->fs_bsize * NDADDR - 1; /* XXX */ 707 for (i = 0; i < NIADDR; i++) { /* XXX */ 708 sizepb *= NINDIR(fs); /* XXX */ 709 fs->fs_maxfilesize += sizepb; /* XXX */ 710 } /* XXX */ 711#endif 712 fs->fs_maxfilesize = (u_quad_t) 1LL << 39; 713 fs->fs_qbmask = ~fs->fs_bmask; /* XXX */ 714 fs->fs_qfmask = ~fs->fs_fmask; /* XXX */ 715 } /* XXX */ 716 return (0); 717} 718 719/* 720 * unmount system call 721 */ 722int 723ffs_unmount(mp, mntflags, p) 724 struct mount *mp; 725 int mntflags; 726 struct proc *p; 727{ 728 register struct ufsmount *ump; 729 register struct fs *fs; 730 int error, flags; 731 732 flags = 0; 733 if (mntflags & MNT_FORCE) { 734 flags |= FORCECLOSE; 735 } 736 error = ffs_flushfiles(mp, flags, p); 737 if (error) 738 return (error); 739 ump = VFSTOUFS(mp); 740 fs = ump->um_fs; 741 if (fs->fs_ronly == 0) { 742 fs->fs_clean = 1; 743 error = ffs_sbupdate(ump, MNT_WAIT); 744 if (error) { 745 fs->fs_clean = 0; 746 return (error); 747 } 748 } 749 ump->um_devvp->v_specflags &= ~SI_MOUNTEDON; 750 751 vinvalbuf(ump->um_devvp, V_SAVE, NOCRED, p, 0, 0); 752 error = VOP_CLOSE(ump->um_devvp, fs->fs_ronly ? FREAD : FREAD|FWRITE, 753 NOCRED, p); 754 755 vrele(ump->um_devvp); 756 757 free(fs->fs_csp[0], M_UFSMNT); 758 free(fs, M_UFSMNT); 759 free(ump, M_UFSMNT); 760 mp->mnt_data = (qaddr_t)0; 761 mp->mnt_flag &= ~MNT_LOCAL; 762 return (error); 763} 764 765/* 766 * Flush out all the files in a filesystem. 767 */ 768int 769ffs_flushfiles(mp, flags, p) 770 register struct mount *mp; 771 int flags; 772 struct proc *p; 773{ 774 register struct ufsmount *ump; 775 int error; 776 777 ump = VFSTOUFS(mp); 778#ifdef QUOTA 779 if (mp->mnt_flag & MNT_QUOTA) { 780 int i; 781 error = vflush(mp, NULLVP, SKIPSYSTEM|flags); 782 if (error) 783 return (error); 784 for (i = 0; i < MAXQUOTAS; i++) { 785 if (ump->um_quotas[i] == NULLVP) 786 continue; 787 quotaoff(p, mp, i); 788 } 789 /* 790 * Here we fall through to vflush again to ensure 791 * that we have gotten rid of all the system vnodes. 792 */ 793 } 794#endif 795 error = vflush(mp, NULLVP, flags); 796 return (error); 797} 798 799/* 800 * Get file system statistics. 801 */ 802int 803ffs_statfs(mp, sbp, p) 804 struct mount *mp; 805 register struct statfs *sbp; 806 struct proc *p; 807{ 808 register struct ufsmount *ump; 809 register struct fs *fs; 810 811 ump = VFSTOUFS(mp); 812 fs = ump->um_fs; 813 if (fs->fs_magic != FS_MAGIC) 814 panic("ffs_statfs"); 815 sbp->f_bsize = fs->fs_fsize; 816 sbp->f_iosize = fs->fs_bsize; 817 sbp->f_blocks = fs->fs_dsize; 818 sbp->f_bfree = fs->fs_cstotal.cs_nbfree * fs->fs_frag + 819 fs->fs_cstotal.cs_nffree; 820 sbp->f_bavail = freespace(fs, fs->fs_minfree); 821 sbp->f_files = fs->fs_ncg * fs->fs_ipg - ROOTINO; 822 sbp->f_ffree = fs->fs_cstotal.cs_nifree; 823 if (sbp != &mp->mnt_stat) { 824 sbp->f_type = mp->mnt_vfc->vfc_typenum; 825 bcopy((caddr_t)mp->mnt_stat.f_mntonname, 826 (caddr_t)&sbp->f_mntonname[0], MNAMELEN); 827 bcopy((caddr_t)mp->mnt_stat.f_mntfromname, 828 (caddr_t)&sbp->f_mntfromname[0], MNAMELEN); 829 } 830 return (0); 831} 832 833/* 834 * Go through the disk queues to initiate sandbagged IO; 835 * go through the inodes to write those that have been modified; 836 * initiate the writing of the super block if it has been modified. 837 * 838 * Note: we are always called with the filesystem marked `MPBUSY'. 839 */ 840int 841ffs_sync(mp, waitfor, cred, p) 842 struct mount *mp; 843 int waitfor; 844 struct ucred *cred; 845 struct proc *p; 846{ 847 struct vnode *nvp, *vp; 848 struct inode *ip; 849 struct ufsmount *ump = VFSTOUFS(mp); 850 struct fs *fs; 851 struct timeval tv; 852 int error, allerror = 0; 853 854 fs = ump->um_fs; 855 if (fs->fs_fmod != 0 && fs->fs_ronly != 0) { /* XXX */ 856 printf("fs = %s\n", fs->fs_fsmnt); 857 panic("ffs_sync: rofs mod"); 858 } 859 /* 860 * Write back each (modified) inode. 861 */ 862 simple_lock(&mntvnode_slock); 863loop: 864 for (vp = mp->mnt_vnodelist.lh_first; vp != NULL; vp = nvp) { 865 /* 866 * If the vnode that we are about to sync is no longer 867 * associated with this mount point, start over. 868 */ 869 if (vp->v_mount != mp) 870 goto loop; 871 simple_lock(&vp->v_interlock); 872 nvp = vp->v_mntvnodes.le_next; 873 ip = VTOI(vp); 874 if (((ip->i_flag & 875 (IN_ACCESS | IN_CHANGE | IN_MODIFIED | IN_UPDATE)) == 0) && 876 vp->v_dirtyblkhd.lh_first == NULL) { 877 simple_unlock(&vp->v_interlock); 878 continue; 879 } 880 if (vp->v_type != VCHR) { 881 simple_unlock(&mntvnode_slock); 882 error = 883 vget(vp, LK_EXCLUSIVE | LK_NOWAIT | LK_INTERLOCK, p); 884 if (error) { 885 simple_lock(&mntvnode_slock); 886 if (error == ENOENT) 887 goto loop; 888 continue; 889 } 890 if (error = VOP_FSYNC(vp, cred, waitfor, p)) 891 allerror = error; 892 VOP_UNLOCK(vp, 0, p); 893 vrele(vp); 894 simple_lock(&mntvnode_slock); 895 } else { 896 simple_unlock(&mntvnode_slock); 897 simple_unlock(&vp->v_interlock); 898 gettime(&tv); 899 /* UFS_UPDATE(vp, &tv, &tv, waitfor == MNT_WAIT); */ 900 UFS_UPDATE(vp, &tv, &tv, 0); 901 simple_lock(&mntvnode_slock); 902 } 903 } 904 simple_unlock(&mntvnode_slock); 905 /* 906 * Force stale file system control information to be flushed. 907 */ 908 error = VOP_FSYNC(ump->um_devvp, cred, waitfor, p); 909 if (error) 910 allerror = error; 911#ifdef QUOTA 912 qsync(mp); 913#endif 914 /* 915 * Write back modified superblock. 916 */ 917 if (fs->fs_fmod != 0) { 918 fs->fs_fmod = 0; 919 fs->fs_time = time.tv_sec; 920 if (error = ffs_sbupdate(ump, waitfor)) 921 allerror = error; 922 } 923 return (allerror); 924} 925 926/* 927 * Look up a FFS dinode number to find its incore vnode, otherwise read it 928 * in from disk. If it is in core, wait for the lock bit to clear, then 929 * return the inode locked. Detection and handling of mount points must be 930 * done by the calling routine. 931 */ 932static int ffs_inode_hash_lock; 933 934int 935ffs_vget(mp, ino, vpp) 936 struct mount *mp; 937 ino_t ino; 938 struct vnode **vpp; 939{ 940 struct fs *fs; 941 struct inode *ip; 942 struct ufsmount *ump; 943 struct buf *bp; 944 struct vnode *vp; 945 dev_t dev; 946 int error; 947 948 ump = VFSTOUFS(mp); 949 dev = ump->um_dev; 950restart: 951 if ((*vpp = ufs_ihashget(dev, ino)) != NULL) 952 return (0); 953 954 /* 955 * Lock out the creation of new entries in the FFS hash table in 956 * case getnewvnode() or MALLOC() blocks, otherwise a duplicate 957 * may occur! 958 */ 959 if (ffs_inode_hash_lock) { 960 while (ffs_inode_hash_lock) { 961 ffs_inode_hash_lock = -1; 962 tsleep(&ffs_inode_hash_lock, PVM, "ffsvgt", 0); 963 } 964 goto restart; 965 } 966 ffs_inode_hash_lock = 1; 967 968 /* 969 * If this MALLOC() is performed after the getnewvnode() 970 * it might block, leaving a vnode with a NULL v_data to be 971 * found by ffs_sync() if a sync happens to fire right then, 972 * which will cause a panic because ffs_sync() blindly 973 * dereferences vp->v_data (as well it should). 974 */ 975 MALLOC(ip, struct inode *, sizeof(struct inode), 976 ump->um_malloctype, M_WAITOK); 977 978 /* Allocate a new vnode/inode. */ 979 error = getnewvnode(VT_UFS, mp, ffs_vnodeop_p, &vp); 980 if (error) { 981 if (ffs_inode_hash_lock < 0) 982 wakeup(&ffs_inode_hash_lock); 983 ffs_inode_hash_lock = 0; 984 *vpp = NULL; 985 FREE(ip, ump->um_malloctype); 986 return (error); 987 } 988 bzero((caddr_t)ip, sizeof(struct inode)); 989 lockinit(&ip->i_lock, PINOD, "inode", 0, 0); 990 vp->v_data = ip; 991 ip->i_vnode = vp; 992 ip->i_fs = fs = ump->um_fs; 993 ip->i_dev = dev; 994 ip->i_number = ino; 995#ifdef QUOTA 996 { 997 int i; 998 for (i = 0; i < MAXQUOTAS; i++) 999 ip->i_dquot[i] = NODQUOT; 1000 } 1001#endif 1002 /* 1003 * Put it onto its hash chain and lock it so that other requests for 1004 * this inode will block if they arrive while we are sleeping waiting 1005 * for old data structures to be purged or for the contents of the 1006 * disk portion of this inode to be read. 1007 */ 1008 ufs_ihashins(ip); 1009 1010 if (ffs_inode_hash_lock < 0) 1011 wakeup(&ffs_inode_hash_lock); 1012 ffs_inode_hash_lock = 0; 1013 1014 /* Read in the disk contents for the inode, copy into the inode. */ 1015 error = bread(ump->um_devvp, fsbtodb(fs, ino_to_fsba(fs, ino)), 1016 (int)fs->fs_bsize, NOCRED, &bp); 1017 if (error) { 1018 /* 1019 * The inode does not contain anything useful, so it would 1020 * be misleading to leave it on its hash chain. With mode 1021 * still zero, it will be unlinked and returned to the free 1022 * list by vput(). 1023 */ 1024 brelse(bp); 1025 vput(vp); 1026 *vpp = NULL; 1027 return (error); 1028 } 1029 ip->i_din = *((struct dinode *)bp->b_data + ino_to_fsbo(fs, ino)); 1030 bqrelse(bp); 1031 1032 /* 1033 * Initialize the vnode from the inode, check for aliases. 1034 * Note that the underlying vnode may have changed. 1035 */ 1036 error = ufs_vinit(mp, ffs_specop_p, ffs_fifoop_p, &vp); 1037 if (error) { 1038 vput(vp); 1039 *vpp = NULL; 1040 return (error); 1041 } 1042 /* 1043 * Finish inode initialization now that aliasing has been resolved. 1044 */ 1045 ip->i_devvp = ump->um_devvp; 1046 VREF(ip->i_devvp); 1047 /* 1048 * Set up a generation number for this inode if it does not 1049 * already have one. This should only happen on old filesystems. 1050 */ 1051 if (ip->i_gen == 0) { 1052 ip->i_gen = random() / 2 + 1; 1053 if ((vp->v_mount->mnt_flag & MNT_RDONLY) == 0) 1054 ip->i_flag |= IN_MODIFIED; 1055 } 1056 /* 1057 * Ensure that uid and gid are correct. This is a temporary 1058 * fix until fsck has been changed to do the update. 1059 */ 1060 if (fs->fs_inodefmt < FS_44INODEFMT) { /* XXX */ 1061 ip->i_uid = ip->i_din.di_ouid; /* XXX */ 1062 ip->i_gid = ip->i_din.di_ogid; /* XXX */ 1063 } /* XXX */ 1064 1065 *vpp = vp; 1066 return (0); 1067} 1068 1069/* 1070 * File handle to vnode 1071 * 1072 * Have to be really careful about stale file handles: 1073 * - check that the inode number is valid 1074 * - call ffs_vget() to get the locked inode 1075 * - check for an unallocated inode (i_mode == 0) 1076 * - check that the given client host has export rights and return 1077 * those rights via. exflagsp and credanonp 1078 */ 1079int 1080ffs_fhtovp(mp, fhp, nam, vpp, exflagsp, credanonp) 1081 register struct mount *mp; 1082 struct fid *fhp; 1083 struct sockaddr *nam; 1084 struct vnode **vpp; 1085 int *exflagsp; 1086 struct ucred **credanonp; 1087{ 1088 register struct ufid *ufhp; 1089 struct fs *fs; 1090 1091 ufhp = (struct ufid *)fhp; 1092 fs = VFSTOUFS(mp)->um_fs; 1093 if (ufhp->ufid_ino < ROOTINO || 1094 ufhp->ufid_ino >= fs->fs_ncg * fs->fs_ipg) 1095 return (ESTALE); 1096 return (ufs_check_export(mp, ufhp, nam, vpp, exflagsp, credanonp)); 1097} 1098 1099/* 1100 * Vnode pointer to File handle 1101 */ 1102/* ARGSUSED */ 1103int 1104ffs_vptofh(vp, fhp) 1105 struct vnode *vp; 1106 struct fid *fhp; 1107{ 1108 register struct inode *ip; 1109 register struct ufid *ufhp; 1110 1111 ip = VTOI(vp); 1112 ufhp = (struct ufid *)fhp; 1113 ufhp->ufid_len = sizeof(struct ufid); 1114 ufhp->ufid_ino = ip->i_number; 1115 ufhp->ufid_gen = ip->i_gen; 1116 return (0); 1117} 1118 1119/* 1120 * Initialize the filesystem; just use ufs_init. 1121 */ 1122static int 1123ffs_init(vfsp) 1124 struct vfsconf *vfsp; 1125{ 1126 1127 return (ufs_init(vfsp)); 1128} 1129 1130/* 1131 * Write a superblock and associated information back to disk. 1132 */ 1133static int 1134ffs_sbupdate(mp, waitfor) 1135 struct ufsmount *mp; 1136 int waitfor; 1137{ 1138 register struct fs *dfs, *fs = mp->um_fs; 1139 register struct buf *bp; 1140 int blks; 1141 caddr_t space; 1142 int i, size, error, allerror = 0; 1143 1144 /* 1145 * First write back the summary information. 1146 */ 1147 blks = howmany(fs->fs_cssize, fs->fs_fsize); 1148 space = (caddr_t)fs->fs_csp[0]; 1149 for (i = 0; i < blks; i += fs->fs_frag) { 1150 size = fs->fs_bsize; 1151 if (i + fs->fs_frag > blks) 1152 size = (blks - i) * fs->fs_fsize; 1153 bp = getblk(mp->um_devvp, fsbtodb(fs, fs->fs_csaddr + i), 1154 size, 0, 0); 1155 bcopy(space, bp->b_data, (u_int)size); 1156 space += size; 1157 if (waitfor != MNT_WAIT) 1158 bawrite(bp); 1159 else if (error = bwrite(bp)) 1160 allerror = error; 1161 } 1162 /* 1163 * Now write back the superblock itself. If any errors occurred 1164 * up to this point, then fail so that the superblock avoids 1165 * being written out as clean. 1166 */ 1167 if (allerror) 1168 return (allerror); 1169 bp = getblk(mp->um_devvp, SBLOCK, (int)fs->fs_sbsize, 0, 0); 1170 bcopy((caddr_t)fs, bp->b_data, (u_int)fs->fs_sbsize); 1171 /* Restore compatibility to old file systems. XXX */ 1172 dfs = (struct fs *)bp->b_data; /* XXX */ 1173 if (fs->fs_postblformat == FS_42POSTBLFMT) /* XXX */ 1174 dfs->fs_nrpos = -1; /* XXX */ 1175 if (fs->fs_inodefmt < FS_44INODEFMT) { /* XXX */ 1176 int32_t *lp, tmp; /* XXX */ 1177 /* XXX */ 1178 lp = (int32_t *)&dfs->fs_qbmask; /* XXX */ 1179 tmp = lp[4]; /* XXX */ 1180 for (i = 4; i > 0; i--) /* XXX */ 1181 lp[i] = lp[i-1]; /* XXX */ 1182 lp[0] = tmp; /* XXX */ 1183 } /* XXX */ 1184 dfs->fs_maxfilesize = mp->um_savedmaxfilesize; /* XXX */ 1185 if (waitfor != MNT_WAIT) 1186 bawrite(bp); 1187 else if (error = bwrite(bp)) 1188 allerror = error; 1189 return (allerror); 1190} 1191