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 * $FreeBSD: src/sys/ufs/ffs/ffs_vfsops.c,v 1.117.2.10 2002/06/23 22:34:52 iedowse Exp $ 35 * $DragonFly: src/sys/vfs/ufs/ffs_vfsops.c,v 1.44 2006/05/26 17:07:48 dillon Exp $ 36 */ 37 38 #include "opt_quota.h" 39 40 #include <sys/param.h> 41 #include <sys/systm.h> 42 #include <sys/proc.h> 43 #include <sys/nlookup.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 "quota.h" 54 #include "ufsmount.h" 55 #include "inode.h" 56 #include "ufs_extern.h" 57 58 #include "fs.h" 59 #include "ffs_extern.h" 60 61 #include <vm/vm.h> 62 #include <vm/vm_page.h> 63 #include <vm/vm_zone.h> 64 65 static MALLOC_DEFINE(M_FFSNODE, "FFS node", "FFS vnode private part"); 66 67 static int ffs_sbupdate (struct ufsmount *, int); 68 static int ffs_reload (struct mount *, struct ucred *); 69 static int ffs_oldfscompat (struct fs *); 70 static int ffs_mount (struct mount *, char *, caddr_t, struct ucred *); 71 static int ffs_init (struct vfsconf *); 72 73 static struct vfsops ufs_vfsops = { 74 .vfs_mount = ffs_mount, 75 .vfs_unmount = ffs_unmount, 76 .vfs_root = ufs_root, 77 .vfs_quotactl = ufs_quotactl, 78 .vfs_statfs = ffs_statfs, 79 .vfs_sync = ffs_sync, 80 .vfs_vget = ffs_vget, 81 .vfs_fhtovp = ffs_fhtovp, 82 .vfs_checkexp = ufs_check_export, 83 .vfs_vptofh = ffs_vptofh, 84 .vfs_init = ffs_init, 85 .vfs_uninit = ufs_uninit 86 }; 87 88 VFS_SET(ufs_vfsops, ufs, 0); 89 90 extern struct vnodeopv_entry_desc ffs_vnodeop_entries[]; 91 extern struct vnodeopv_entry_desc ffs_specop_entries[]; 92 extern struct vnodeopv_entry_desc ffs_fifoop_entries[]; 93 94 95 /* 96 * ffs_mount 97 * 98 * Called when mounting local physical media 99 * 100 * PARAMETERS: 101 * mountroot 102 * mp mount point structure 103 * path NULL (flag for root mount!!!) 104 * data <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 * p process (user credentials check) 112 * 113 * RETURNS: 0 Success 114 * !0 error number (errno.h) 115 * 116 * LOCK STATE: 117 * 118 * ENTRY 119 * mount point is locked 120 * EXIT 121 * mount point is locked 122 * 123 * NOTES: 124 * A NULL path can be used for a flag since the mount 125 * system call will fail with EFAULT in copyinstr in 126 * nlookup() if it is a genuine NULL from the user. 127 */ 128 static int 129 ffs_mount(struct mount *mp, /* mount struct pointer */ 130 char *path, /* path to mount point */ 131 caddr_t data, /* arguments to FS specific mount */ 132 struct ucred *cred) /* process requesting mount */ 133 { 134 size_t size; 135 int error; 136 struct vnode *devvp; 137 138 struct ufs_args args; 139 struct ufsmount *ump = 0; 140 struct fs *fs; 141 int flags, ronly = 0; 142 mode_t accessmode; 143 struct nlookupdata nd; 144 struct vnode *rootvp; 145 146 devvp = NULL; 147 error = 0; 148 149 /* 150 * Use NULL path to flag a root mount 151 */ 152 if (path == NULL) { 153 /* 154 *** 155 * Mounting root filesystem 156 *** 157 */ 158 159 if ((error = bdevvp(rootdev, &rootvp))) { 160 printf("ffs_mountroot: can't find rootvp\n"); 161 return (error); 162 } 163 164 if( ( error = ffs_mountfs(rootvp, mp, M_FFSNODE)) != 0) { 165 /* fs specific cleanup (if any)*/ 166 goto error_1; 167 } 168 devvp = rootvp; 169 170 goto dostatfs; /* success*/ 171 172 } 173 174 /* 175 *** 176 * Mounting non-root filesystem or updating a filesystem 177 *** 178 */ 179 180 /* copy in user arguments*/ 181 error = copyin(data, (caddr_t)&args, sizeof (struct ufs_args)); 182 if (error) 183 goto error_1; /* can't get arguments*/ 184 185 /* 186 * If updating, check whether changing from read-only to 187 * read/write; if there is no device name, that's all we do. 188 */ 189 if (mp->mnt_flag & MNT_UPDATE) { 190 ump = VFSTOUFS(mp); 191 fs = ump->um_fs; 192 devvp = ump->um_devvp; 193 error = 0; 194 ronly = fs->fs_ronly; /* MNT_RELOAD might change this */ 195 if (ronly == 0 && (mp->mnt_flag & MNT_RDONLY)) { 196 /* 197 * Flush any dirty data. 198 */ 199 VFS_SYNC(mp, MNT_WAIT); 200 /* 201 * Check for and optionally get rid of files open 202 * for writing. 203 */ 204 flags = WRITECLOSE; 205 if (mp->mnt_flag & MNT_FORCE) 206 flags |= FORCECLOSE; 207 if (mp->mnt_flag & MNT_SOFTDEP) { 208 error = softdep_flushfiles(mp, flags); 209 } else { 210 error = ffs_flushfiles(mp, flags); 211 } 212 ronly = 1; 213 } 214 if (!error && (mp->mnt_flag & MNT_RELOAD)) { 215 error = ffs_reload(mp, NULL); 216 } 217 if (error) { 218 goto error_1; 219 } 220 if (ronly && (mp->mnt_kern_flag & MNTK_WANTRDWR)) { 221 /* 222 * If upgrade to read-write by non-root, then verify 223 * that user has necessary permissions on the device. 224 */ 225 if (cred->cr_uid != 0) { 226 vn_lock(devvp, LK_EXCLUSIVE | LK_RETRY); 227 if ((error = VOP_ACCESS(devvp, VREAD | VWRITE, 228 cred)) != 0) { 229 VOP_UNLOCK(devvp, 0); 230 return (error); 231 } 232 VOP_UNLOCK(devvp, 0); 233 } 234 235 fs->fs_flags &= ~FS_UNCLEAN; 236 if (fs->fs_clean == 0) { 237 fs->fs_flags |= FS_UNCLEAN; 238 if (mp->mnt_flag & MNT_FORCE) { 239 printf( 240 "WARNING: %s was not properly dismounted\n", 241 fs->fs_fsmnt); 242 } else { 243 printf( 244 "WARNING: R/W mount of %s denied. Filesystem is not clean - run fsck\n", 245 fs->fs_fsmnt); 246 error = EPERM; 247 goto error_1; 248 } 249 } 250 251 /* check to see if we need to start softdep */ 252 if (fs->fs_flags & FS_DOSOFTDEP) { 253 error = softdep_mount(devvp, mp, fs); 254 if (error) 255 goto error_1; 256 } 257 ronly = 0; 258 } 259 /* 260 * Soft updates is incompatible with "async", 261 * so if we are doing softupdates stop the user 262 * from setting the async flag in an update. 263 * Softdep_mount() clears it in an initial mount 264 * or ro->rw remount. 265 */ 266 if (mp->mnt_flag & MNT_SOFTDEP) { 267 mp->mnt_flag &= ~MNT_ASYNC; 268 } 269 /* if not updating name...*/ 270 if (args.fspec == 0) { 271 /* 272 * Process export requests. Jumping to "success" 273 * will return the vfs_export() error code. 274 */ 275 error = vfs_export(mp, &ump->um_export, &args.export); 276 goto success; 277 } 278 } 279 280 /* 281 * Not an update, or updating the name: look up the name 282 * and verify that it refers to a sensible block device. 283 */ 284 devvp = NULL; 285 error = nlookup_init(&nd, args.fspec, UIO_USERSPACE, NLC_FOLLOW); 286 if (error == 0) 287 error = nlookup(&nd); 288 if (error == 0) 289 error = cache_vref(nd.nl_ncp, nd.nl_cred, &devvp); 290 nlookup_done(&nd); 291 if (error) 292 goto error_1; 293 294 if (!vn_isdisk(devvp, &error)) 295 goto error_2; 296 297 /* 298 * If mount by non-root, then verify that user has necessary 299 * permissions on the device. 300 */ 301 if (cred->cr_uid != 0) { 302 accessmode = VREAD; 303 if ((mp->mnt_flag & MNT_RDONLY) == 0) 304 accessmode |= VWRITE; 305 vn_lock(devvp, LK_EXCLUSIVE | LK_RETRY); 306 if ((error = VOP_ACCESS(devvp, accessmode, cred)) != 0) { 307 vput(devvp); 308 return (error); 309 } 310 VOP_UNLOCK(devvp, 0); 311 } 312 313 if (mp->mnt_flag & MNT_UPDATE) { 314 /* 315 * UPDATE - make sure the resolved vnode represents the same 316 * device. Note that devvp->v_rdev may be NULL since we 317 * haven't opened it, so compare udev instead. 318 * 319 * Our current open/writecount state is associated with 320 * um_devvp, so continue using um_devvp and throw away devvp. 321 */ 322 if (devvp != ump->um_devvp) { 323 if (devvp->v_udev == ump->um_devvp->v_udev) { 324 vrele(devvp); 325 devvp = ump->um_devvp; 326 } else { 327 printf("cannot update mount, udev does" 328 " not match %08x vs %08x\n", 329 devvp->v_udev, ump->um_devvp->v_udev); 330 error = EINVAL; /* needs translation */ 331 } 332 } else { 333 vrele(devvp); 334 } 335 /* 336 * Update device name only on success 337 */ 338 if (!error) { 339 /* Save "mounted from" info for mount point (NULL pad)*/ 340 copyinstr( args.fspec, 341 mp->mnt_stat.f_mntfromname, 342 MNAMELEN - 1, 343 &size); 344 bzero( mp->mnt_stat.f_mntfromname + size, MNAMELEN - size); 345 } 346 } else { 347 /* 348 ******************** 349 * NEW MOUNT 350 ******************** 351 */ 352 353 /* Save "mounted from" info for mount point (NULL pad)*/ 354 copyinstr( args.fspec, /* device name*/ 355 mp->mnt_stat.f_mntfromname, /* save area*/ 356 MNAMELEN - 1, /* max size*/ 357 &size); /* real size*/ 358 bzero( mp->mnt_stat.f_mntfromname + size, MNAMELEN - size); 359 360 error = ffs_mountfs(devvp, mp, M_FFSNODE); 361 } 362 if (error) { 363 goto error_2; 364 } 365 366 dostatfs: 367 /* 368 * Initialize FS stat information in mount struct; uses 369 * mp->mnt_stat.f_mntfromname. 370 * 371 * This code is common to root and non-root mounts 372 */ 373 (void)VFS_STATFS(mp, &mp->mnt_stat, cred); 374 375 goto success; 376 377 378 error_2: /* error with devvp held*/ 379 380 /* release devvp before failing*/ 381 vrele(devvp); 382 383 error_1: /* no state to back out*/ 384 385 success: 386 if (!error && path && (mp->mnt_flag & MNT_UPDATE)) { 387 /* Update clean flag after changing read-onlyness. */ 388 fs = ump->um_fs; 389 if (ronly != fs->fs_ronly) { 390 fs->fs_ronly = ronly; 391 fs->fs_clean = ronly && 392 (fs->fs_flags & FS_UNCLEAN) == 0 ? 1 : 0; 393 394 /* 395 * The device must be re-opened as appropriate or 396 * the device close at unmount time will panic. 397 */ 398 vn_lock(devvp, LK_EXCLUSIVE | LK_RETRY); 399 if (ronly) { 400 VOP_OPEN(devvp, FREAD, FSCRED, NULL); 401 VOP_CLOSE(devvp, FREAD|FWRITE); 402 } else { 403 VOP_OPEN(devvp, FREAD|FWRITE, FSCRED, NULL); 404 VOP_CLOSE(devvp, FREAD); 405 } 406 VOP_UNLOCK(devvp, 0); 407 ffs_sbupdate(ump, MNT_WAIT); 408 } 409 } 410 return (error); 411 } 412 413 /* 414 * Reload all incore data for a filesystem (used after running fsck on 415 * the root filesystem and finding things to fix). The filesystem must 416 * be mounted read-only. 417 * 418 * Things to do to update the mount: 419 * 1) invalidate all cached meta-data. 420 * 2) re-read superblock from disk. 421 * 3) re-read summary information from disk. 422 * 4) invalidate all inactive vnodes. 423 * 5) invalidate all cached file data. 424 * 6) re-read inode data for all active vnodes. 425 */ 426 427 static int ffs_reload_scan2(struct mount *mp, struct vnode *vp, void *data); 428 429 struct scaninfo { 430 int rescan; 431 struct fs *fs; 432 struct vnode *devvp; 433 int waitfor; 434 int allerror; 435 }; 436 437 static int 438 ffs_reload(struct mount *mp, struct ucred *cred) 439 { 440 struct vnode *devvp; 441 void *space; 442 struct buf *bp; 443 struct fs *fs, *newfs; 444 struct partinfo dpart; 445 dev_t dev; 446 int i, blks, size, error; 447 struct scaninfo scaninfo; 448 int32_t *lp; 449 450 if ((mp->mnt_flag & MNT_RDONLY) == 0) 451 return (EINVAL); 452 /* 453 * Step 1: invalidate all cached meta-data. 454 */ 455 devvp = VFSTOUFS(mp)->um_devvp; 456 vn_lock(devvp, LK_EXCLUSIVE | LK_RETRY); 457 error = vinvalbuf(devvp, 0, 0, 0); 458 VOP_UNLOCK(devvp, 0); 459 if (error) 460 panic("ffs_reload: dirty1"); 461 462 dev = devvp->v_rdev; 463 464 /* 465 * The backing device must be VMIO-capable because we use getblk(). 466 * NOTE: the MFS driver now returns a VMIO-enabled descriptor. 467 */ 468 if (devvp->v_object == NULL) 469 panic("ffs_reload: devvp has no VM object!"); 470 471 /* 472 * Step 2: re-read superblock from disk. 473 */ 474 if (VOP_IOCTL(devvp, DIOCGPART, (caddr_t)&dpart, FREAD, NOCRED) != 0) 475 size = DEV_BSIZE; 476 else 477 size = dpart.disklab->d_secsize; 478 if ((error = bread(devvp, SBOFF, SBSIZE, &bp)) != 0) { 479 brelse(bp); 480 return (error); 481 } 482 newfs = (struct fs *)bp->b_data; 483 if (newfs->fs_magic != FS_MAGIC || newfs->fs_bsize > MAXBSIZE || 484 newfs->fs_bsize < sizeof(struct fs)) { 485 brelse(bp); 486 return (EIO); /* XXX needs translation */ 487 } 488 fs = VFSTOUFS(mp)->um_fs; 489 /* 490 * Copy pointer fields back into superblock before copying in XXX 491 * new superblock. These should really be in the ufsmount. XXX 492 * Note that important parameters (eg fs_ncg) are unchanged. 493 */ 494 newfs->fs_csp = fs->fs_csp; 495 newfs->fs_maxcluster = fs->fs_maxcluster; 496 newfs->fs_contigdirs = fs->fs_contigdirs; 497 /* The filesystem is still read-only. */ 498 newfs->fs_ronly = 1; 499 bcopy(newfs, fs, (uint)fs->fs_sbsize); 500 if (fs->fs_sbsize < SBSIZE) 501 bp->b_flags |= B_INVAL; 502 brelse(bp); 503 mp->mnt_maxsymlinklen = fs->fs_maxsymlinklen; 504 ffs_oldfscompat(fs); 505 /* An old fsck may have zeroed these fields, so recheck them. */ 506 if (fs->fs_avgfilesize <= 0) /* XXX */ 507 fs->fs_avgfilesize = AVFILESIZ; /* XXX */ 508 if (fs->fs_avgfpdir <= 0) /* XXX */ 509 fs->fs_avgfpdir = AFPDIR; /* XXX */ 510 511 /* 512 * Step 3: re-read summary information from disk. 513 */ 514 blks = howmany(fs->fs_cssize, fs->fs_fsize); 515 space = fs->fs_csp; 516 for (i = 0; i < blks; i += fs->fs_frag) { 517 size = fs->fs_bsize; 518 if (i + fs->fs_frag > blks) 519 size = (blks - i) * fs->fs_fsize; 520 error = bread(devvp, fsbtodoff(fs, fs->fs_csaddr + i), size, &bp); 521 if (error) { 522 brelse(bp); 523 return (error); 524 } 525 bcopy(bp->b_data, space, (uint)size); 526 space = (char *)space + size; 527 brelse(bp); 528 } 529 /* 530 * We no longer know anything about clusters per cylinder group. 531 */ 532 if (fs->fs_contigsumsize > 0) { 533 lp = fs->fs_maxcluster; 534 for (i = 0; i < fs->fs_ncg; i++) 535 *lp++ = fs->fs_contigsumsize; 536 } 537 538 scaninfo.rescan = 0; 539 scaninfo.fs = fs; 540 scaninfo.devvp = devvp; 541 while (error == 0 && scaninfo.rescan) { 542 scaninfo.rescan = 0; 543 error = vmntvnodescan(mp, VMSC_GETVX, 544 NULL, ffs_reload_scan2, &scaninfo); 545 } 546 return(error); 547 } 548 549 static int 550 ffs_reload_scan2(struct mount *mp, struct vnode *vp, void *data) 551 { 552 struct scaninfo *info = data; 553 struct inode *ip; 554 struct buf *bp; 555 int error; 556 557 /* 558 * Try to recycle 559 */ 560 if (vrecycle(vp)) 561 return(0); 562 563 if (vinvalbuf(vp, 0, 0, 0)) 564 panic("ffs_reload: dirty2"); 565 /* 566 * Step 6: re-read inode data for all active vnodes. 567 */ 568 ip = VTOI(vp); 569 error = bread(info->devvp, 570 fsbtodoff(info->fs, ino_to_fsba(info->fs, ip->i_number)), 571 (int)info->fs->fs_bsize, &bp); 572 if (error) { 573 brelse(bp); 574 return (error); 575 } 576 ip->i_din = *((struct ufs1_dinode *)bp->b_data + 577 ino_to_fsbo(info->fs, ip->i_number)); 578 ip->i_effnlink = ip->i_nlink; 579 brelse(bp); 580 return(0); 581 } 582 583 /* 584 * Common code for mount and mountroot 585 */ 586 int 587 ffs_mountfs(struct vnode *devvp, struct mount *mp, struct malloc_type *mtype) 588 { 589 struct ufsmount *ump; 590 struct buf *bp; 591 struct fs *fs; 592 dev_t dev; 593 struct partinfo dpart; 594 void *space; 595 int error, i, blks, size, ronly; 596 int32_t *lp; 597 uint64_t maxfilesize; /* XXX */ 598 599 /* 600 * Disallow multiple mounts of the same device. 601 * Disallow mounting of a device that is currently in use 602 * Flush out any old buffers remaining from a previous use. 603 */ 604 error = vfs_mountedon(devvp); 605 if (error) 606 return (error); 607 if (count_udev(devvp->v_udev) > 0) 608 return (EBUSY); 609 vn_lock(devvp, LK_EXCLUSIVE | LK_RETRY); 610 error = vinvalbuf(devvp, V_SAVE, 0, 0); 611 VOP_UNLOCK(devvp, 0); 612 if (error) 613 return (error); 614 615 ronly = (mp->mnt_flag & MNT_RDONLY) != 0; 616 vn_lock(devvp, LK_EXCLUSIVE | LK_RETRY); 617 error = VOP_OPEN(devvp, ronly ? FREAD : FREAD|FWRITE, FSCRED, NULL); 618 VOP_UNLOCK(devvp, 0); 619 if (error) 620 return (error); 621 dev = devvp->v_rdev; 622 if (dev->si_iosize_max != 0) 623 mp->mnt_iosize_max = dev->si_iosize_max; 624 if (mp->mnt_iosize_max > MAXPHYS) 625 mp->mnt_iosize_max = MAXPHYS; 626 627 /* 628 * The backing device must be VMIO-capable because we use getblk(). 629 * NOTE: the MFS driver now returns a VMIO-enabled descriptor. 630 * The VOP_OPEN() call above should have associated a VM object 631 * with devvp. 632 */ 633 if (devvp->v_object == NULL) 634 panic("ffs_reload: devvp has no VM object!"); 635 636 if (VOP_IOCTL(devvp, DIOCGPART, (caddr_t)&dpart, FREAD, proc0.p_ucred) != 0) 637 size = DEV_BSIZE; 638 else 639 size = dpart.disklab->d_secsize; 640 641 bp = NULL; 642 ump = NULL; 643 if ((error = bread(devvp, SBOFF, SBSIZE, &bp)) != 0) 644 goto out; 645 fs = (struct fs *)bp->b_data; 646 if (fs->fs_magic != FS_MAGIC || fs->fs_bsize > MAXBSIZE || 647 fs->fs_bsize < sizeof(struct fs)) { 648 error = EINVAL; /* XXX needs translation */ 649 goto out; 650 } 651 fs->fs_fmod = 0; 652 fs->fs_flags &= ~FS_UNCLEAN; 653 if (fs->fs_clean == 0) { 654 fs->fs_flags |= FS_UNCLEAN; 655 if (ronly || (mp->mnt_flag & MNT_FORCE)) { 656 printf( 657 "WARNING: %s was not properly dismounted\n", 658 fs->fs_fsmnt); 659 } else { 660 printf( 661 "WARNING: R/W mount of %s denied. Filesystem is not clean - run fsck\n", 662 fs->fs_fsmnt); 663 error = EPERM; 664 goto out; 665 } 666 } 667 /* XXX updating 4.2 FFS superblocks trashes rotational layout tables */ 668 if (fs->fs_postblformat == FS_42POSTBLFMT && !ronly) { 669 error = EROFS; /* needs translation */ 670 goto out; 671 } 672 ump = malloc(sizeof *ump, M_UFSMNT, M_WAITOK); 673 bzero((caddr_t)ump, sizeof *ump); 674 ump->um_malloctype = mtype; 675 ump->um_i_effnlink_valid = 1; 676 ump->um_fs = malloc((u_long)fs->fs_sbsize, M_UFSMNT, 677 M_WAITOK); 678 bcopy(bp->b_data, ump->um_fs, (uint)fs->fs_sbsize); 679 if (fs->fs_sbsize < SBSIZE) 680 bp->b_flags |= B_INVAL; 681 brelse(bp); 682 bp = NULL; 683 fs = ump->um_fs; 684 fs->fs_ronly = ronly; 685 size = fs->fs_cssize; 686 blks = howmany(size, fs->fs_fsize); 687 if (fs->fs_contigsumsize > 0) 688 size += fs->fs_ncg * sizeof(int32_t); 689 size += fs->fs_ncg * sizeof(uint8_t); 690 space = malloc((u_long)size, M_UFSMNT, M_WAITOK); 691 fs->fs_csp = space; 692 for (i = 0; i < blks; i += fs->fs_frag) { 693 size = fs->fs_bsize; 694 if (i + fs->fs_frag > blks) 695 size = (blks - i) * fs->fs_fsize; 696 if ((error = bread(devvp, fsbtodoff(fs, fs->fs_csaddr + i), 697 size, &bp)) != 0) { 698 free(fs->fs_csp, M_UFSMNT); 699 goto out; 700 } 701 bcopy(bp->b_data, space, (uint)size); 702 space = (char *)space + size; 703 brelse(bp); 704 bp = NULL; 705 } 706 if (fs->fs_contigsumsize > 0) { 707 fs->fs_maxcluster = lp = space; 708 for (i = 0; i < fs->fs_ncg; i++) 709 *lp++ = fs->fs_contigsumsize; 710 space = lp; 711 } 712 size = fs->fs_ncg * sizeof(uint8_t); 713 fs->fs_contigdirs = (uint8_t *)space; 714 bzero(fs->fs_contigdirs, size); 715 /* Compatibility for old filesystems XXX */ 716 if (fs->fs_avgfilesize <= 0) /* XXX */ 717 fs->fs_avgfilesize = AVFILESIZ; /* XXX */ 718 if (fs->fs_avgfpdir <= 0) /* XXX */ 719 fs->fs_avgfpdir = AFPDIR; /* XXX */ 720 mp->mnt_data = (qaddr_t)ump; 721 mp->mnt_stat.f_fsid.val[0] = fs->fs_id[0]; 722 mp->mnt_stat.f_fsid.val[1] = fs->fs_id[1]; 723 if (fs->fs_id[0] == 0 || fs->fs_id[1] == 0 || 724 vfs_getvfs(&mp->mnt_stat.f_fsid)) 725 vfs_getnewfsid(mp); 726 mp->mnt_maxsymlinklen = fs->fs_maxsymlinklen; 727 mp->mnt_flag |= MNT_LOCAL; 728 ump->um_mountp = mp; 729 ump->um_dev = dev; 730 ump->um_devvp = devvp; 731 ump->um_nindir = fs->fs_nindir; 732 ump->um_bptrtodb = fs->fs_fsbtodb; 733 ump->um_seqinc = fs->fs_frag; 734 for (i = 0; i < MAXQUOTAS; i++) 735 ump->um_quotas[i] = NULLVP; 736 dev->si_mountpoint = mp; 737 ffs_oldfscompat(fs); 738 739 if( mp->mnt_flag & MNT_ROOTFS) { 740 /* 741 * Root mount; update timestamp in mount structure. 742 * this will be used by the common root mount code 743 * to update the system clock. 744 */ 745 mp->mnt_time = fs->fs_time; 746 } 747 748 ump->um_savedmaxfilesize = fs->fs_maxfilesize; /* XXX */ 749 maxfilesize = (uint64_t)0x40000000 * fs->fs_bsize - 1; /* XXX */ 750 /* Enforce limit caused by vm object backing (32 bits vm_pindex_t). */ 751 if (maxfilesize > (uint64_t)0x80000000u * PAGE_SIZE - 1) 752 maxfilesize = (uint64_t)0x80000000u * PAGE_SIZE - 1; 753 if (fs->fs_maxfilesize > maxfilesize) /* XXX */ 754 fs->fs_maxfilesize = maxfilesize; /* XXX */ 755 if (ronly == 0) { 756 if ((fs->fs_flags & FS_DOSOFTDEP) && 757 (error = softdep_mount(devvp, mp, fs)) != 0) { 758 free(fs->fs_csp, M_UFSMNT); 759 goto out; 760 } 761 fs->fs_fmod = 1; 762 fs->fs_clean = 0; 763 (void) ffs_sbupdate(ump, MNT_WAIT); 764 } 765 vfs_add_vnodeops(mp, &mp->mnt_vn_norm_ops, ffs_vnodeop_entries, VVF_SUPPORTS_FSMID); 766 vfs_add_vnodeops(mp, &mp->mnt_vn_spec_ops, ffs_specop_entries, VVF_SUPPORTS_FSMID); 767 vfs_add_vnodeops(mp, &mp->mnt_vn_fifo_ops, ffs_fifoop_entries, VVF_SUPPORTS_FSMID); 768 769 return (0); 770 out: 771 dev->si_mountpoint = NULL; 772 if (bp) 773 brelse(bp); 774 VOP_CLOSE(devvp, ronly ? FREAD : FREAD|FWRITE); 775 if (ump) { 776 free(ump->um_fs, M_UFSMNT); 777 free(ump, M_UFSMNT); 778 mp->mnt_data = (qaddr_t)0; 779 } 780 return (error); 781 } 782 783 /* 784 * Sanity checks for old filesystems. 785 * 786 * XXX - goes away some day. 787 */ 788 static int 789 ffs_oldfscompat(struct fs *fs) 790 { 791 fs->fs_npsect = max(fs->fs_npsect, fs->fs_nsect); /* XXX */ 792 fs->fs_interleave = max(fs->fs_interleave, 1); /* XXX */ 793 if (fs->fs_postblformat == FS_42POSTBLFMT) /* XXX */ 794 fs->fs_nrpos = 8; /* XXX */ 795 if (fs->fs_inodefmt < FS_44INODEFMT) { /* XXX */ 796 #if 0 797 int i; /* XXX */ 798 uint64_t sizepb = fs->fs_bsize; /* XXX */ 799 /* XXX */ 800 fs->fs_maxfilesize = fs->fs_bsize * NDADDR - 1; /* XXX */ 801 for (i = 0; i < NIADDR; i++) { /* XXX */ 802 sizepb *= NINDIR(fs); /* XXX */ 803 fs->fs_maxfilesize += sizepb; /* XXX */ 804 } /* XXX */ 805 #endif 806 fs->fs_maxfilesize = (u_quad_t) 1LL << 39; 807 fs->fs_qbmask = ~fs->fs_bmask; /* XXX */ 808 fs->fs_qfmask = ~fs->fs_fmask; /* XXX */ 809 } /* XXX */ 810 return (0); 811 } 812 813 /* 814 * unmount system call 815 */ 816 int 817 ffs_unmount(struct mount *mp, int mntflags) 818 { 819 struct ufsmount *ump; 820 struct fs *fs; 821 int error, flags; 822 823 flags = 0; 824 if (mntflags & MNT_FORCE) { 825 flags |= FORCECLOSE; 826 } 827 if (mp->mnt_flag & MNT_SOFTDEP) { 828 if ((error = softdep_flushfiles(mp, flags)) != 0) 829 return (error); 830 } else { 831 if ((error = ffs_flushfiles(mp, flags)) != 0) 832 return (error); 833 } 834 ump = VFSTOUFS(mp); 835 fs = ump->um_fs; 836 if (fs->fs_ronly == 0) { 837 fs->fs_clean = fs->fs_flags & FS_UNCLEAN ? 0 : 1; 838 error = ffs_sbupdate(ump, MNT_WAIT); 839 if (error) { 840 fs->fs_clean = 0; 841 return (error); 842 } 843 } 844 ump->um_devvp->v_rdev->si_mountpoint = NULL; 845 846 vinvalbuf(ump->um_devvp, V_SAVE, 0, 0); 847 error = VOP_CLOSE(ump->um_devvp, fs->fs_ronly ? FREAD : FREAD|FWRITE); 848 849 vrele(ump->um_devvp); 850 851 free(fs->fs_csp, M_UFSMNT); 852 free(fs, M_UFSMNT); 853 free(ump, M_UFSMNT); 854 mp->mnt_data = (qaddr_t)0; 855 mp->mnt_flag &= ~MNT_LOCAL; 856 return (error); 857 } 858 859 /* 860 * Flush out all the files in a filesystem. 861 */ 862 int 863 ffs_flushfiles(struct mount *mp, int flags) 864 { 865 struct ufsmount *ump; 866 int error; 867 868 ump = VFSTOUFS(mp); 869 #ifdef QUOTA 870 if (mp->mnt_flag & MNT_QUOTA) { 871 int i; 872 error = vflush(mp, 0, SKIPSYSTEM|flags); 873 if (error) 874 return (error); 875 /* Find out how many quota files we have open. */ 876 for (i = 0; i < MAXQUOTAS; i++) { 877 if (ump->um_quotas[i] == NULLVP) 878 continue; 879 ufs_quotaoff(mp, i); 880 } 881 /* 882 * Here we fall through to vflush again to ensure 883 * that we have gotten rid of all the system vnodes. 884 */ 885 } 886 #endif 887 /* 888 * Flush all the files. 889 */ 890 if ((error = vflush(mp, 0, flags)) != 0) 891 return (error); 892 /* 893 * Flush filesystem metadata. 894 */ 895 vn_lock(ump->um_devvp, LK_EXCLUSIVE | LK_RETRY); 896 error = VOP_FSYNC(ump->um_devvp, MNT_WAIT); 897 VOP_UNLOCK(ump->um_devvp, 0); 898 return (error); 899 } 900 901 /* 902 * Get filesystem statistics. 903 */ 904 int 905 ffs_statfs(struct mount *mp, struct statfs *sbp, struct ucred *cred) 906 { 907 struct ufsmount *ump; 908 struct fs *fs; 909 910 ump = VFSTOUFS(mp); 911 fs = ump->um_fs; 912 if (fs->fs_magic != FS_MAGIC) 913 panic("ffs_statfs"); 914 sbp->f_bsize = fs->fs_fsize; 915 sbp->f_iosize = fs->fs_bsize; 916 sbp->f_blocks = fs->fs_dsize; 917 sbp->f_bfree = fs->fs_cstotal.cs_nbfree * fs->fs_frag + 918 fs->fs_cstotal.cs_nffree; 919 sbp->f_bavail = freespace(fs, fs->fs_minfree); 920 sbp->f_files = fs->fs_ncg * fs->fs_ipg - ROOTINO; 921 sbp->f_ffree = fs->fs_cstotal.cs_nifree; 922 if (sbp != &mp->mnt_stat) { 923 sbp->f_type = mp->mnt_vfc->vfc_typenum; 924 bcopy((caddr_t)mp->mnt_stat.f_mntfromname, 925 (caddr_t)&sbp->f_mntfromname[0], MNAMELEN); 926 } 927 return (0); 928 } 929 930 /* 931 * Go through the disk queues to initiate sandbagged IO; 932 * go through the inodes to write those that have been modified; 933 * initiate the writing of the super block if it has been modified. 934 * 935 * Note: we are always called with the filesystem marked `MPBUSY'. 936 */ 937 938 939 static int ffs_sync_scan1(struct mount *mp, struct vnode *vp, void *data); 940 static int ffs_sync_scan2(struct mount *mp, struct vnode *vp, void *data); 941 942 int 943 ffs_sync(struct mount *mp, int waitfor) 944 { 945 struct ufsmount *ump = VFSTOUFS(mp); 946 struct fs *fs; 947 int error; 948 struct scaninfo scaninfo; 949 950 fs = ump->um_fs; 951 if (fs->fs_fmod != 0 && fs->fs_ronly != 0) { /* XXX */ 952 printf("fs = %s\n", fs->fs_fsmnt); 953 panic("ffs_sync: rofs mod"); 954 } 955 956 /* 957 * Write back each (modified) inode. 958 */ 959 scaninfo.allerror = 0; 960 scaninfo.rescan = 1; 961 scaninfo.waitfor = waitfor; 962 while (scaninfo.rescan) { 963 scaninfo.rescan = 0; 964 vmntvnodescan(mp, VMSC_GETVP|VMSC_NOWAIT, 965 ffs_sync_scan1, ffs_sync_scan2, &scaninfo); 966 } 967 968 /* 969 * Force stale filesystem control information to be flushed. 970 */ 971 if (waitfor != MNT_LAZY) { 972 if (ump->um_mountp->mnt_flag & MNT_SOFTDEP) 973 waitfor = MNT_NOWAIT; 974 vn_lock(ump->um_devvp, LK_EXCLUSIVE | LK_RETRY); 975 if ((error = VOP_FSYNC(ump->um_devvp, waitfor)) != 0) 976 scaninfo.allerror = error; 977 VOP_UNLOCK(ump->um_devvp, 0); 978 } 979 #ifdef QUOTA 980 ufs_qsync(mp); 981 #endif 982 /* 983 * Write back modified superblock. 984 */ 985 if (fs->fs_fmod != 0 && (error = ffs_sbupdate(ump, waitfor)) != 0) 986 scaninfo.allerror = error; 987 return (scaninfo.allerror); 988 } 989 990 static int 991 ffs_sync_scan1(struct mount *mp, struct vnode *vp, void *data) 992 { 993 struct inode *ip; 994 995 /* 996 * Depend on the mount list's vnode lock to keep things stable 997 * enough for a quick test. Since there might be hundreds of 998 * thousands of vnodes, we cannot afford even a subroutine 999 * call unless there's a good chance that we have work to do. 1000 */ 1001 ip = VTOI(vp); 1002 /* Restart out whole search if this guy is locked 1003 * or is being reclaimed. 1004 */ 1005 if (vp->v_type == VNON || ((ip->i_flag & 1006 (IN_ACCESS | IN_CHANGE | IN_MODIFIED | IN_UPDATE)) == 0 && 1007 RB_EMPTY(&vp->v_rbdirty_tree))) { 1008 return(-1); 1009 } 1010 return(0); 1011 } 1012 1013 static int 1014 ffs_sync_scan2(struct mount *mp, struct vnode *vp, void *data) 1015 { 1016 struct scaninfo *info = data; 1017 struct inode *ip; 1018 int error; 1019 1020 /* 1021 * We have to recheck after having obtained the vnode interlock. 1022 */ 1023 ip = VTOI(vp); 1024 if (vp->v_type == VNON || ((ip->i_flag & 1025 (IN_ACCESS | IN_CHANGE | IN_MODIFIED | IN_UPDATE)) == 0 && 1026 RB_EMPTY(&vp->v_rbdirty_tree))) { 1027 return(0); 1028 } 1029 if (vp->v_type != VCHR) { 1030 if ((error = VOP_FSYNC(vp, info->waitfor)) != 0) 1031 info->allerror = error; 1032 } else { 1033 /* 1034 * We must reference the vp to prevent it from 1035 * getting ripped out from under ffs_update, since 1036 * we are not holding a vnode lock. 1037 */ 1038 /* ffs_update(vp, waitfor == MNT_WAIT); */ 1039 ffs_update(vp, 0); 1040 } 1041 return(0); 1042 } 1043 1044 /* 1045 * Look up a FFS dinode number to find its incore vnode, otherwise read it 1046 * in from disk. If it is in core, wait for the lock bit to clear, then 1047 * return the inode locked. Detection and handling of mount points must be 1048 * done by the calling routine. 1049 */ 1050 1051 int 1052 ffs_vget(struct mount *mp, ino_t ino, struct vnode **vpp) 1053 { 1054 struct fs *fs; 1055 struct inode *ip; 1056 struct ufsmount *ump; 1057 struct buf *bp; 1058 struct vnode *vp; 1059 dev_t dev; 1060 int error; 1061 1062 ump = VFSTOUFS(mp); 1063 dev = ump->um_dev; 1064 restart: 1065 if ((*vpp = ufs_ihashget(dev, ino)) != NULL) { 1066 return (0); 1067 } 1068 1069 /* 1070 * If this MALLOC() is performed after the getnewvnode() 1071 * it might block, leaving a vnode with a NULL v_data to be 1072 * found by ffs_sync() if a sync happens to fire right then, 1073 * which will cause a panic because ffs_sync() blindly 1074 * dereferences vp->v_data (as well it should). 1075 * 1076 * XXX this may no longer be true since getnewvnode returns a 1077 * VX locked vnode now. 1078 */ 1079 MALLOC(ip, struct inode *, sizeof(struct inode), 1080 ump->um_malloctype, M_WAITOK); 1081 1082 /* Allocate a new vnode/inode. */ 1083 error = getnewvnode(VT_UFS, mp, &vp, VLKTIMEOUT, LK_CANRECURSE); 1084 if (error) { 1085 *vpp = NULL; 1086 free(ip, ump->um_malloctype); 1087 return (error); 1088 } 1089 bzero((caddr_t)ip, sizeof(struct inode)); 1090 ip->i_vnode = vp; 1091 ip->i_fs = fs = ump->um_fs; 1092 ip->i_dev = dev; 1093 ip->i_number = ino; 1094 #ifdef QUOTA 1095 { 1096 int i; 1097 for (i = 0; i < MAXQUOTAS; i++) 1098 ip->i_dquot[i] = NODQUOT; 1099 } 1100 #endif 1101 1102 /* 1103 * Insert it into the inode hash table and check for a collision. 1104 * If a collision occurs, throw away the vnode and try again. 1105 */ 1106 if (ufs_ihashins(ip) != 0) { 1107 printf("debug: ufs ihashins collision, retrying inode %ld\n", 1108 (long)ip->i_number); 1109 vx_put(vp); 1110 free(ip, ump->um_malloctype); 1111 goto restart; 1112 } 1113 vp->v_data = ip; 1114 1115 /* Read in the disk contents for the inode, copy into the inode. */ 1116 error = bread(ump->um_devvp, fsbtodoff(fs, ino_to_fsba(fs, ino)), 1117 (int)fs->fs_bsize, &bp); 1118 if (error) { 1119 /* 1120 * The inode does not contain anything useful, so it would 1121 * be misleading to leave it on its hash chain. With mode 1122 * still zero, it will be unlinked and returned to the free 1123 * list by vput(). 1124 */ 1125 brelse(bp); 1126 vx_put(vp); 1127 *vpp = NULL; 1128 return (error); 1129 } 1130 ip->i_din = *((struct ufs1_dinode *)bp->b_data + ino_to_fsbo(fs, ino)); 1131 if (DOINGSOFTDEP(vp)) 1132 softdep_load_inodeblock(ip); 1133 else 1134 ip->i_effnlink = ip->i_nlink; 1135 bqrelse(bp); 1136 1137 /* 1138 * Initialize the vnode from the inode, check for aliases. 1139 * Note that the underlying vnode may have changed. 1140 */ 1141 error = ufs_vinit(mp, &vp); 1142 if (error) { 1143 vx_put(vp); 1144 *vpp = NULL; 1145 return (error); 1146 } 1147 /* 1148 * Finish inode initialization now that aliasing has been resolved. 1149 */ 1150 ip->i_devvp = ump->um_devvp; 1151 vref(ip->i_devvp); 1152 /* 1153 * Set up a generation number for this inode if it does not 1154 * already have one. This should only happen on old filesystems. 1155 */ 1156 if (ip->i_gen == 0) { 1157 ip->i_gen = random() / 2 + 1; 1158 if ((vp->v_mount->mnt_flag & MNT_RDONLY) == 0) 1159 ip->i_flag |= IN_MODIFIED; 1160 } 1161 /* 1162 * Ensure that uid and gid are correct. This is a temporary 1163 * fix until fsck has been changed to do the update. 1164 */ 1165 if (fs->fs_inodefmt < FS_44INODEFMT) { /* XXX */ 1166 ip->i_uid = ip->i_din.di_ouid; /* XXX */ 1167 ip->i_gid = ip->i_din.di_ogid; /* XXX */ 1168 } /* XXX */ 1169 1170 /* 1171 * return a VX locked and refd vnode (VX == same as normal vget() 1172 * vnode so we are ok) 1173 */ 1174 *vpp = vp; 1175 return (0); 1176 } 1177 1178 /* 1179 * File handle to vnode 1180 * 1181 * Have to be really careful about stale file handles: 1182 * - check that the inode number is valid 1183 * - call ffs_vget() to get the locked inode 1184 * - check for an unallocated inode (i_mode == 0) 1185 * - check that the given client host has export rights and return 1186 * those rights via. exflagsp and credanonp 1187 */ 1188 int 1189 ffs_fhtovp(struct mount *mp, struct fid *fhp, struct vnode **vpp) 1190 { 1191 struct ufid *ufhp; 1192 struct fs *fs; 1193 1194 ufhp = (struct ufid *)fhp; 1195 fs = VFSTOUFS(mp)->um_fs; 1196 if (ufhp->ufid_ino < ROOTINO || 1197 ufhp->ufid_ino >= fs->fs_ncg * fs->fs_ipg) 1198 return (ESTALE); 1199 return (ufs_fhtovp(mp, ufhp, vpp)); 1200 } 1201 1202 /* 1203 * Vnode pointer to File handle 1204 */ 1205 /* ARGSUSED */ 1206 int 1207 ffs_vptofh(struct vnode *vp, struct fid *fhp) 1208 { 1209 struct inode *ip; 1210 struct ufid *ufhp; 1211 1212 ip = VTOI(vp); 1213 ufhp = (struct ufid *)fhp; 1214 ufhp->ufid_len = sizeof(struct ufid); 1215 ufhp->ufid_ino = ip->i_number; 1216 ufhp->ufid_gen = ip->i_gen; 1217 return (0); 1218 } 1219 1220 /* 1221 * Initialize the filesystem; just use ufs_init. 1222 */ 1223 static int 1224 ffs_init(struct vfsconf *vfsp) 1225 { 1226 softdep_initialize(); 1227 return (ufs_init(vfsp)); 1228 } 1229 1230 /* 1231 * Write a superblock and associated information back to disk. 1232 */ 1233 static int 1234 ffs_sbupdate(struct ufsmount *mp, int waitfor) 1235 { 1236 struct fs *dfs, *fs = mp->um_fs; 1237 struct buf *bp; 1238 int blks; 1239 void *space; 1240 int i, size, error, allerror = 0; 1241 1242 /* 1243 * First write back the summary information. 1244 * 1245 * NOTE: the getblk is relative to the device vnode so bio1 1246 * contains the device block number. 1247 */ 1248 blks = howmany(fs->fs_cssize, fs->fs_fsize); 1249 space = fs->fs_csp; 1250 for (i = 0; i < blks; i += fs->fs_frag) { 1251 size = fs->fs_bsize; 1252 if (i + fs->fs_frag > blks) 1253 size = (blks - i) * fs->fs_fsize; 1254 bp = getblk(mp->um_devvp, fsbtodoff(fs, fs->fs_csaddr + i), 1255 size, 0, 0); 1256 bcopy(space, bp->b_data, (uint)size); 1257 space = (char *)space + size; 1258 if (waitfor != MNT_WAIT) 1259 bawrite(bp); 1260 else if ((error = bwrite(bp)) != 0) 1261 allerror = error; 1262 } 1263 /* 1264 * Now write back the superblock itself. If any errors occurred 1265 * up to this point, then fail so that the superblock avoids 1266 * being written out as clean. 1267 */ 1268 if (allerror) 1269 return (allerror); 1270 bp = getblk(mp->um_devvp, SBOFF, (int)fs->fs_sbsize, 0, 0); 1271 fs->fs_fmod = 0; 1272 fs->fs_time = time_second; 1273 bcopy((caddr_t)fs, bp->b_data, (uint)fs->fs_sbsize); 1274 /* Restore compatibility to old filesystems. XXX */ 1275 dfs = (struct fs *)bp->b_data; /* XXX */ 1276 if (fs->fs_postblformat == FS_42POSTBLFMT) /* XXX */ 1277 dfs->fs_nrpos = -1; /* XXX */ 1278 if (fs->fs_inodefmt < FS_44INODEFMT) { /* XXX */ 1279 int32_t *lp, tmp; /* XXX */ 1280 /* XXX */ 1281 lp = (int32_t *)&dfs->fs_qbmask; /* XXX */ 1282 tmp = lp[4]; /* XXX */ 1283 for (i = 4; i > 0; i--) /* XXX */ 1284 lp[i] = lp[i-1]; /* XXX */ 1285 lp[0] = tmp; /* XXX */ 1286 } /* XXX */ 1287 dfs->fs_maxfilesize = mp->um_savedmaxfilesize; /* XXX */ 1288 if (waitfor != MNT_WAIT) 1289 bawrite(bp); 1290 else if ((error = bwrite(bp)) != 0) 1291 allerror = error; 1292 return (allerror); 1293 } 1294