1/* $NetBSD: ffs_vfsops.c,v 1.382 2023/09/08 23:21:55 riastradh Exp $ */ 2 3/*- 4 * Copyright (c) 2008, 2009 The NetBSD Foundation, Inc. 5 * All rights reserved. 6 * 7 * This code is derived from software contributed to The NetBSD Foundation 8 * by Wasabi Systems, Inc, and by Andrew Doran. 9 * 10 * Redistribution and use in source and binary forms, with or without 11 * modification, are permitted provided that the following conditions 12 * are met: 13 * 1. Redistributions of source code must retain the above copyright 14 * notice, this list of conditions and the following disclaimer. 15 * 2. Redistributions in binary form must reproduce the above copyright 16 * notice, this list of conditions and the following disclaimer in the 17 * documentation and/or other materials provided with the distribution. 18 * 19 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 20 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 21 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 22 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 23 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 24 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 25 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 26 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 27 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 29 * POSSIBILITY OF SUCH DAMAGE. 30 */ 31 32/* 33 * Copyright (c) 1989, 1991, 1993, 1994 34 * The Regents of the University of California. All rights reserved. 35 * 36 * Redistribution and use in source and binary forms, with or without 37 * modification, are permitted provided that the following conditions 38 * are met: 39 * 1. Redistributions of source code must retain the above copyright 40 * notice, this list of conditions and the following disclaimer. 41 * 2. Redistributions in binary form must reproduce the above copyright 42 * notice, this list of conditions and the following disclaimer in the 43 * documentation and/or other materials provided with the distribution. 44 * 3. Neither the name of the University nor the names of its contributors 45 * may be used to endorse or promote products derived from this software 46 * without specific prior written permission. 47 * 48 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 49 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 50 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 51 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 52 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 53 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 54 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 55 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 56 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 57 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 58 * SUCH DAMAGE. 59 * 60 * @(#)ffs_vfsops.c 8.31 (Berkeley) 5/20/95 61 */ 62 63#include <sys/cdefs.h> 64__KERNEL_RCSID(0, "$NetBSD: ffs_vfsops.c,v 1.382 2023/09/08 23:21:55 riastradh Exp $"); 65 66#if defined(_KERNEL_OPT) 67#include "opt_ffs.h" 68#include "opt_quota.h" 69#include "opt_wapbl.h" 70#endif 71 72#include <sys/param.h> 73#include <sys/systm.h> 74#include <sys/namei.h> 75#include <sys/proc.h> 76#include <sys/kernel.h> 77#include <sys/vnode.h> 78#include <sys/fstrans.h> 79#include <sys/socket.h> 80#include <sys/mount.h> 81#include <sys/buf.h> 82#include <sys/device.h> 83#include <sys/disk.h> 84#include <sys/file.h> 85#include <sys/disklabel.h> 86#include <sys/ioctl.h> 87#include <sys/errno.h> 88#include <sys/kmem.h> 89#include <sys/pool.h> 90#include <sys/lock.h> 91#include <sys/sysctl.h> 92#include <sys/conf.h> 93#include <sys/kauth.h> 94#include <sys/wapbl.h> 95#include <sys/module.h> 96 97#include <miscfs/genfs/genfs.h> 98#include <miscfs/specfs/specdev.h> 99 100#include <ufs/ufs/quota.h> 101#include <ufs/ufs/ufsmount.h> 102#include <ufs/ufs/inode.h> 103#include <ufs/ufs/dir.h> 104#include <ufs/ufs/ufs_extern.h> 105#include <ufs/ufs/ufs_bswap.h> 106#include <ufs/ufs/ufs_wapbl.h> 107 108#include <ufs/ffs/fs.h> 109#include <ufs/ffs/ffs_extern.h> 110 111#ifdef WAPBL 112MODULE(MODULE_CLASS_VFS, ffs, "ufs,wapbl"); 113#else 114MODULE(MODULE_CLASS_VFS, ffs, "ufs"); 115#endif 116 117static int ffs_vfs_fsync(vnode_t *, int); 118static int ffs_superblock_validate(struct fs *); 119static int ffs_is_appleufs(struct vnode *, struct fs *); 120 121static int ffs_init_vnode(struct ufsmount *, struct vnode *, ino_t); 122static void ffs_deinit_vnode(struct ufsmount *, struct vnode *); 123 124static kauth_listener_t ffs_snapshot_listener; 125 126/* how many times ffs_init() was called */ 127int ffs_initcount = 0; 128 129#ifdef DEBUG_FFS_MOUNT 130#define DPRINTF(_fmt, args...) printf("%s: " _fmt "\n", __func__, ##args) 131#else 132#define DPRINTF(_fmt, args...) do {} while (/*CONSTCOND*/0) 133#endif 134 135extern const struct vnodeopv_desc ffs_vnodeop_opv_desc; 136extern const struct vnodeopv_desc ffs_specop_opv_desc; 137extern const struct vnodeopv_desc ffs_fifoop_opv_desc; 138 139const struct vnodeopv_desc * const ffs_vnodeopv_descs[] = { 140 &ffs_vnodeop_opv_desc, 141 &ffs_specop_opv_desc, 142 &ffs_fifoop_opv_desc, 143 NULL, 144}; 145 146struct vfsops ffs_vfsops = { 147 .vfs_name = MOUNT_FFS, 148 .vfs_min_mount_data = sizeof (struct ufs_args), 149 .vfs_mount = ffs_mount, 150 .vfs_start = ufs_start, 151 .vfs_unmount = ffs_unmount, 152 .vfs_root = ufs_root, 153 .vfs_quotactl = ufs_quotactl, 154 .vfs_statvfs = ffs_statvfs, 155 .vfs_sync = ffs_sync, 156 .vfs_vget = ufs_vget, 157 .vfs_loadvnode = ffs_loadvnode, 158 .vfs_newvnode = ffs_newvnode, 159 .vfs_fhtovp = ffs_fhtovp, 160 .vfs_vptofh = ffs_vptofh, 161 .vfs_init = ffs_init, 162 .vfs_reinit = ffs_reinit, 163 .vfs_done = ffs_done, 164 .vfs_mountroot = ffs_mountroot, 165 .vfs_snapshot = ffs_snapshot, 166 .vfs_extattrctl = ffs_extattrctl, 167 .vfs_suspendctl = genfs_suspendctl, 168 .vfs_renamelock_enter = genfs_renamelock_enter, 169 .vfs_renamelock_exit = genfs_renamelock_exit, 170 .vfs_fsync = ffs_vfs_fsync, 171 .vfs_opv_descs = ffs_vnodeopv_descs 172}; 173 174static const struct genfs_ops ffs_genfsops = { 175 .gop_size = ffs_gop_size, 176 .gop_alloc = ufs_gop_alloc, 177 .gop_write = genfs_gop_write, 178 .gop_markupdate = ufs_gop_markupdate, 179 .gop_putrange = genfs_gop_putrange, 180}; 181 182static const struct ufs_ops ffs_ufsops = { 183 .uo_itimes = ffs_itimes, 184 .uo_update = ffs_update, 185 .uo_truncate = ffs_truncate, 186 .uo_balloc = ffs_balloc, 187 .uo_snapgone = ffs_snapgone, 188 .uo_bufrd = ffs_bufrd, 189 .uo_bufwr = ffs_bufwr, 190}; 191 192static int 193ffs_checkrange(struct mount *mp, ino_t ino) 194{ 195 struct fs *fs = VFSTOUFS(mp)->um_fs; 196 197 if (ino < UFS_ROOTINO || ino >= fs->fs_ncg * fs->fs_ipg) { 198 DPRINTF("out of range %" PRIu64 "\n", ino); 199 return ESTALE; 200 } 201 202 /* 203 * Need to check if inode is initialized because ffsv2 does 204 * lazy initialization and we can get here from nfs_fhtovp 205 */ 206 if (fs->fs_magic != FS_UFS2_MAGIC) 207 return 0; 208 209 struct buf *bp; 210 int cg = ino_to_cg(fs, ino); 211 struct ufsmount *ump = VFSTOUFS(mp); 212 213 int error = bread(ump->um_devvp, FFS_FSBTODB(fs, cgtod(fs, cg)), 214 (int)fs->fs_cgsize, B_MODIFY, &bp); 215 if (error) { 216 DPRINTF("error %d reading cg %d ino %" PRIu64 "\n", 217 error, cg, ino); 218 return error; 219 } 220 221 const int needswap = UFS_FSNEEDSWAP(fs); 222 223 struct cg *cgp = (struct cg *)bp->b_data; 224 if (!cg_chkmagic(cgp, needswap)) { 225 brelse(bp, 0); 226 DPRINTF("bad cylinder group magic cg %d ino %" PRIu64 "\n", 227 cg, ino); 228 return ESTALE; 229 } 230 231 int32_t initediblk = ufs_rw32(cgp->cg_initediblk, needswap); 232 brelse(bp, 0); 233 234 if (cg * fs->fs_ipg + initediblk < ino) { 235 DPRINTF("cg=%d fs->fs_ipg=%d initediblk=%d ino=%" PRIu64 "\n", 236 cg, fs->fs_ipg, initediblk, ino); 237 return ESTALE; 238 } 239 return 0; 240} 241 242static int 243ffs_snapshot_cb(kauth_cred_t cred, kauth_action_t action, void *cookie, 244 void *arg0, void *arg1, void *arg2, void *arg3) 245{ 246 vnode_t *vp = arg2; 247 int result = KAUTH_RESULT_DEFER; 248 249 if (action != KAUTH_SYSTEM_FS_SNAPSHOT) 250 return result; 251 252 if (VTOI(vp)->i_uid == kauth_cred_geteuid(cred)) 253 result = KAUTH_RESULT_ALLOW; 254 255 return result; 256} 257 258SYSCTL_SETUP(ffs_sysctl_setup, "ffs sysctls") 259{ 260#ifdef UFS_EXTATTR 261 extern int ufs_extattr_autocreate; 262#endif 263 extern int ffs_log_changeopt; 264 265 sysctl_createv(clog, 0, NULL, NULL, 266 CTLFLAG_PERMANENT, 267 CTLTYPE_NODE, "ffs", 268 SYSCTL_DESCR("Berkeley Fast File System"), 269 NULL, 0, NULL, 0, 270 CTL_VFS, 1, CTL_EOL); 271 /* 272 * @@@ should we even bother with these first three? 273 */ 274 sysctl_createv(clog, 0, NULL, NULL, 275 CTLFLAG_PERMANENT|CTLFLAG_READWRITE, 276 CTLTYPE_INT, "doclusterread", NULL, 277 sysctl_notavail, 0, NULL, 0, 278 CTL_VFS, 1, FFS_CLUSTERREAD, CTL_EOL); 279 sysctl_createv(clog, 0, NULL, NULL, 280 CTLFLAG_PERMANENT|CTLFLAG_READWRITE, 281 CTLTYPE_INT, "doclusterwrite", NULL, 282 sysctl_notavail, 0, NULL, 0, 283 CTL_VFS, 1, FFS_CLUSTERWRITE, CTL_EOL); 284 sysctl_createv(clog, 0, NULL, NULL, 285 CTLFLAG_PERMANENT|CTLFLAG_READWRITE, 286 CTLTYPE_INT, "doreallocblks", NULL, 287 sysctl_notavail, 0, NULL, 0, 288 CTL_VFS, 1, FFS_REALLOCBLKS, CTL_EOL); 289#if 0 290 sysctl_createv(clog, 0, NULL, NULL, 291 CTLFLAG_PERMANENT|CTLFLAG_READWRITE, 292 CTLTYPE_INT, "doasyncfree", 293 SYSCTL_DESCR("Release dirty blocks asynchronously"), 294 NULL, 0, &doasyncfree, 0, 295 CTL_VFS, 1, FFS_ASYNCFREE, CTL_EOL); 296#endif 297 sysctl_createv(clog, 0, NULL, NULL, 298 CTLFLAG_PERMANENT|CTLFLAG_READWRITE, 299 CTLTYPE_INT, "log_changeopt", 300 SYSCTL_DESCR("Log changes in optimization strategy"), 301 NULL, 0, &ffs_log_changeopt, 0, 302 CTL_VFS, 1, FFS_LOG_CHANGEOPT, CTL_EOL); 303#ifdef UFS_EXTATTR 304 sysctl_createv(clog, 0, NULL, NULL, 305 CTLFLAG_PERMANENT|CTLFLAG_READWRITE, 306 CTLTYPE_INT, "extattr_autocreate", 307 SYSCTL_DESCR("Size of attribute for " 308 "backing file autocreation"), 309 NULL, 0, &ufs_extattr_autocreate, 0, 310 CTL_VFS, 1, FFS_EXTATTR_AUTOCREATE, CTL_EOL); 311 312#endif /* UFS_EXTATTR */ 313} 314 315static int 316ffs_modcmd(modcmd_t cmd, void *arg) 317{ 318 int error; 319 320#if 0 321 extern int doasyncfree; 322#endif 323 324 switch (cmd) { 325 case MODULE_CMD_INIT: 326 error = vfs_attach(&ffs_vfsops); 327 if (error != 0) 328 break; 329 330 ffs_snapshot_listener = kauth_listen_scope(KAUTH_SCOPE_SYSTEM, 331 ffs_snapshot_cb, NULL); 332 if (ffs_snapshot_listener == NULL) 333 printf("ffs_modcmd: can't listen on system scope.\n"); 334 335 break; 336 case MODULE_CMD_FINI: 337 error = vfs_detach(&ffs_vfsops); 338 if (error != 0) 339 break; 340 if (ffs_snapshot_listener != NULL) 341 kauth_unlisten_scope(ffs_snapshot_listener); 342 break; 343 default: 344 error = ENOTTY; 345 break; 346 } 347 348 return (error); 349} 350 351pool_cache_t ffs_inode_cache; 352pool_cache_t ffs_dinode1_cache; 353pool_cache_t ffs_dinode2_cache; 354 355static void ffs_oldfscompat_read(struct fs *, struct ufsmount *, daddr_t); 356static void ffs_oldfscompat_write(struct fs *, struct ufsmount *); 357 358/* 359 * Called by main() when ffs is going to be mounted as root. 360 */ 361 362int 363ffs_mountroot(void) 364{ 365 struct fs *fs; 366 struct mount *mp; 367 struct lwp *l = curlwp; /* XXX */ 368 struct ufsmount *ump; 369 int error; 370 371 if (device_class(root_device) != DV_DISK) 372 return (ENODEV); 373 374 if ((error = vfs_rootmountalloc(MOUNT_FFS, "root_device", &mp))) { 375 vrele(rootvp); 376 return (error); 377 } 378 379 /* 380 * We always need to be able to mount the root file system. 381 */ 382 mp->mnt_flag |= MNT_FORCE; 383 if ((error = ffs_mountfs(rootvp, mp, l)) != 0) { 384 vfs_unbusy(mp); 385 vfs_rele(mp); 386 return (error); 387 } 388 mp->mnt_flag &= ~MNT_FORCE; 389 mountlist_append(mp); 390 ump = VFSTOUFS(mp); 391 fs = ump->um_fs; 392 memset(fs->fs_fsmnt, 0, sizeof(fs->fs_fsmnt)); 393 (void)copystr(mp->mnt_stat.f_mntonname, fs->fs_fsmnt, MNAMELEN - 1, 0); 394 (void)ffs_statvfs(mp, &mp->mnt_stat); 395 vfs_unbusy(mp); 396 setrootfstime((time_t)fs->fs_time); 397 return (0); 398} 399 400static int 401ffs_acls(struct mount *mp, int fs_flags) 402{ 403 struct ufsmount *ump; 404 405 ump = VFSTOUFS(mp); 406 if (ump->um_fstype == UFS2 && (ump->um_flags & UFS_EA) == 0 && 407 ((mp->mnt_flag & (MNT_POSIX1EACLS | MNT_NFS4ACLS)) != 0 || 408 (fs_flags & (FS_POSIX1EACLS | FS_NFS4ACLS)) != 0)) { 409 printf("%s: ACLs requested but not supported by this fs\n", 410 mp->mnt_stat.f_mntonname); 411 return EINVAL; 412 } 413 414 if ((fs_flags & FS_POSIX1EACLS) != 0) { 415#ifdef UFS_ACL 416 if (mp->mnt_flag & MNT_NFS4ACLS) 417 printf("WARNING: %s: POSIX.1e ACLs flag on fs conflicts " 418 "with \"nfsv4acls\" mount option; option ignored\n", 419 mp->mnt_stat.f_mntonname); 420 mp->mnt_flag &= ~MNT_NFS4ACLS; 421 mp->mnt_flag |= MNT_POSIX1EACLS; 422#else 423 printf("WARNING: %s: POSIX.1e ACLs flag on fs but no " 424 "ACLs support\n", mp->mnt_stat.f_mntonname); 425#endif 426 } 427 if ((fs_flags & FS_NFS4ACLS) != 0) { 428#ifdef UFS_ACL 429 if (mp->mnt_flag & MNT_POSIX1EACLS) 430 printf("WARNING: %s: NFSv4 ACLs flag on fs conflicts " 431 "with \"posix1eacls\" mount option; option ignored\n", 432 mp->mnt_stat.f_mntonname); 433 mp->mnt_flag &= ~MNT_POSIX1EACLS; 434 mp->mnt_flag |= MNT_NFS4ACLS; 435 436#else 437 printf("WARNING: %s: NFSv4 ACLs flag on fs but no " 438 "ACLs support\n", mp->mnt_stat.f_mntonname); 439#endif 440 } 441 if ((mp->mnt_flag & (MNT_NFS4ACLS | MNT_POSIX1EACLS)) 442 == (MNT_NFS4ACLS | MNT_POSIX1EACLS)) 443 { 444 printf("%s: \"posix1eacls\" and \"nfsv4acls\" options " 445 "are mutually exclusive\n", 446 mp->mnt_stat.f_mntonname); 447 return EINVAL; 448 } 449 450 if (mp->mnt_flag & (MNT_NFS4ACLS | MNT_POSIX1EACLS)) 451 mp->mnt_iflag &= ~(IMNT_SHRLOOKUP|IMNT_NCLOOKUP); 452 else 453 mp->mnt_iflag |= IMNT_SHRLOOKUP|IMNT_NCLOOKUP; 454 return 0; 455} 456 457/* 458 * VFS Operations. 459 * 460 * mount system call 461 */ 462int 463ffs_mount(struct mount *mp, const char *path, void *data, size_t *data_len) 464{ 465 struct lwp *l = curlwp; 466 struct vnode *devvp = NULL; 467 struct ufs_args *args = data; 468 struct ufsmount *ump = NULL; 469 struct fs *fs; 470 int error = 0, flags, update; 471 mode_t accessmode; 472 473 if (args == NULL) { 474 DPRINTF("NULL args"); 475 return EINVAL; 476 } 477 if (*data_len < sizeof(*args)) { 478 DPRINTF("bad size args %zu != %zu", *data_len, sizeof(*args)); 479 return EINVAL; 480 } 481 482 ump = VFSTOUFS(mp); 483 if ((mp->mnt_flag & (MNT_GETARGS|MNT_UPDATE)) && ump == NULL) { 484 DPRINTF("no ump"); 485 return EIO; 486 } 487 488 if (mp->mnt_flag & MNT_GETARGS) { 489 args->fspec = NULL; 490 *data_len = sizeof *args; 491 return 0; 492 } 493 494 update = mp->mnt_flag & MNT_UPDATE; 495 496 /* Check arguments */ 497 if (args->fspec == NULL) { 498 if (!update) { 499 /* New mounts must have a filename for the device */ 500 DPRINTF("no filename for mount"); 501 return EINVAL; 502 } 503 } else { 504 /* 505 * Look up the name and verify that it's sane. 506 */ 507 error = namei_simple_user(args->fspec, 508 NSM_FOLLOW_NOEMULROOT, &devvp); 509 if (error != 0) { 510 DPRINTF("namei_simple_user returned %d", error); 511 return error; 512 } 513 514 /* 515 * Be sure this is a valid block device 516 */ 517 if (devvp->v_type != VBLK) { 518 DPRINTF("non block device %d", devvp->v_type); 519 error = ENOTBLK; 520 goto fail; 521 } 522 523 if (bdevsw_lookup(devvp->v_rdev) == NULL) { 524 DPRINTF("can't find block device 0x%jx", 525 devvp->v_rdev); 526 error = ENXIO; 527 goto fail; 528 } 529 530 if (update) { 531 /* 532 * Be sure we're still naming the same device 533 * used for our initial mount 534 */ 535 if (devvp != ump->um_devvp && 536 devvp->v_rdev != ump->um_devvp->v_rdev) { 537 DPRINTF("wrong device 0x%jx != 0x%jx", 538 (uintmax_t)devvp->v_rdev, 539 (uintmax_t)ump->um_devvp->v_rdev); 540 error = EINVAL; 541 goto fail; 542 } 543 vrele(devvp); 544 devvp = NULL; 545 } 546 } 547 548 if (devvp == NULL) { 549 devvp = ump->um_devvp; 550 vref(devvp); 551 } 552 553 /* 554 * If mount by non-root, then verify that user has necessary 555 * permissions on the device. 556 * 557 * Permission to update a mount is checked higher, so here we presume 558 * updating the mount is okay (for example, as far as securelevel goes) 559 * which leaves us with the normal check. 560 */ 561 accessmode = VREAD; 562 if (update ? (mp->mnt_iflag & IMNT_WANTRDWR) != 0 : 563 (mp->mnt_flag & MNT_RDONLY) == 0) 564 accessmode |= VWRITE; 565 vn_lock(devvp, LK_EXCLUSIVE | LK_RETRY); 566 error = kauth_authorize_system(l->l_cred, KAUTH_SYSTEM_MOUNT, 567 KAUTH_REQ_SYSTEM_MOUNT_DEVICE, mp, devvp, KAUTH_ARG(accessmode)); 568 VOP_UNLOCK(devvp); 569 if (error) { 570 DPRINTF("kauth returned %d", error); 571 goto fail; 572 } 573 574#ifdef WAPBL 575 /* WAPBL can only be enabled on a r/w mount. */ 576 if (((mp->mnt_flag & MNT_RDONLY) && !(mp->mnt_iflag & IMNT_WANTRDWR)) || 577 (mp->mnt_iflag & IMNT_WANTRDONLY)) { 578 mp->mnt_flag &= ~MNT_LOG; 579 } 580#else /* !WAPBL */ 581 mp->mnt_flag &= ~MNT_LOG; 582#endif /* !WAPBL */ 583 584 error = set_statvfs_info(path, UIO_USERSPACE, args->fspec, 585 UIO_USERSPACE, mp->mnt_op->vfs_name, mp, l); 586 if (error) 587 goto fail; 588 589 if (!update) { 590 int xflags; 591 592 if (mp->mnt_flag & MNT_RDONLY) 593 xflags = FREAD; 594 else 595 xflags = FREAD | FWRITE; 596 vn_lock(devvp, LK_EXCLUSIVE | LK_RETRY); 597 error = VOP_OPEN(devvp, xflags, FSCRED); 598 VOP_UNLOCK(devvp); 599 if (error) { 600 DPRINTF("VOP_OPEN returned %d", error); 601 goto fail; 602 } 603 /* Need fstrans_start() for assertion in ufs_strategy(). */ 604 if ((mp->mnt_flag & MNT_RDONLY) == 0) 605 fstrans_start(mp); 606 error = ffs_mountfs(devvp, mp, l); 607 if ((mp->mnt_flag & MNT_RDONLY) == 0) 608 fstrans_done(mp); 609 if (error) { 610 DPRINTF("ffs_mountfs returned %d", error); 611 vn_lock(devvp, LK_EXCLUSIVE | LK_RETRY); 612 (void)VOP_CLOSE(devvp, xflags, NOCRED); 613 VOP_UNLOCK(devvp); 614 goto fail; 615 } 616 617 ump = VFSTOUFS(mp); 618 fs = ump->um_fs; 619 } else { 620 /* 621 * Update the mount. 622 */ 623 624 /* 625 * The initial mount got a reference on this 626 * device, so drop the one obtained via 627 * namei(), above. 628 */ 629 vrele(devvp); 630 631 ump = VFSTOUFS(mp); 632 fs = ump->um_fs; 633 if (fs->fs_ronly == 0 && (mp->mnt_iflag & IMNT_WANTRDONLY)) { 634 /* 635 * Changing from r/w to r/o 636 */ 637 flags = WRITECLOSE; 638 if (mp->mnt_flag & MNT_FORCE) 639 flags |= FORCECLOSE; 640 error = ffs_flushfiles(mp, flags, l); 641 if (error) 642 return error; 643 644 error = UFS_WAPBL_BEGIN(mp); 645 if (error) { 646 DPRINTF("wapbl %d", error); 647 return error; 648 } 649 650 if (ffs_cgupdate(ump, MNT_WAIT) == 0 && 651 fs->fs_clean & FS_WASCLEAN) { 652 if (mp->mnt_flag & MNT_SOFTDEP) 653 fs->fs_flags &= ~FS_DOSOFTDEP; 654 fs->fs_clean = FS_ISCLEAN; 655 (void) ffs_sbupdate(ump, MNT_WAIT); 656 } 657 658 UFS_WAPBL_END(mp); 659 } 660 661#ifdef WAPBL 662 if ((mp->mnt_flag & MNT_LOG) == 0) { 663 error = ffs_wapbl_stop(mp, mp->mnt_flag & MNT_FORCE); 664 if (error) { 665 DPRINTF("ffs_wapbl_stop returned %d", error); 666 return error; 667 } 668 } 669#endif /* WAPBL */ 670 671 if (fs->fs_ronly == 0 && (mp->mnt_iflag & IMNT_WANTRDONLY)) { 672 /* 673 * Finish change from r/w to r/o 674 */ 675 fs->fs_ronly = 1; 676 fs->fs_fmod = 0; 677 } 678 679 error = ffs_acls(mp, fs->fs_flags); 680 if (error) 681 return error; 682 if (mp->mnt_flag & MNT_RELOAD) { 683 error = ffs_reload(mp, l->l_cred, l); 684 if (error) { 685 DPRINTF("ffs_reload returned %d", error); 686 return error; 687 } 688 } 689 690 if (fs->fs_ronly && (mp->mnt_iflag & IMNT_WANTRDWR)) { 691 /* 692 * Changing from read-only to read/write 693 */ 694#ifndef QUOTA2 695 if (fs->fs_flags & FS_DOQUOTA2) { 696 ump->um_flags |= UFS_QUOTA2; 697 uprintf("%s: options QUOTA2 not enabled%s\n", 698 mp->mnt_stat.f_mntonname, 699 (mp->mnt_flag & MNT_FORCE) ? "" : 700 ", not mounting"); 701 DPRINTF("ffs_quota2 %d", EINVAL); 702 return EINVAL; 703 } 704#endif 705 fs->fs_ronly = 0; 706 fs->fs_clean = 707 fs->fs_clean == FS_ISCLEAN ? FS_WASCLEAN : 0; 708 fs->fs_fmod = 1; 709#ifdef WAPBL 710 if (fs->fs_flags & FS_DOWAPBL) { 711 const char *nm = mp->mnt_stat.f_mntonname; 712 if (!mp->mnt_wapbl_replay) { 713 printf("%s: log corrupted;" 714 " replay cancelled\n", nm); 715 return EFTYPE; 716 } 717 printf("%s: replaying log to disk\n", nm); 718 error = wapbl_replay_write(mp->mnt_wapbl_replay, 719 devvp); 720 if (error) { 721 DPRINTF("%s: wapbl_replay_write %d", 722 nm, error); 723 return error; 724 } 725 wapbl_replay_stop(mp->mnt_wapbl_replay); 726 fs->fs_clean = FS_WASCLEAN; 727 } 728#endif /* WAPBL */ 729 if (fs->fs_snapinum[0] != 0) 730 ffs_snapshot_mount(mp); 731 } 732 733#ifdef WAPBL 734 error = ffs_wapbl_start(mp); 735 if (error) { 736 DPRINTF("ffs_wapbl_start returned %d", error); 737 return error; 738 } 739#endif /* WAPBL */ 740 741#ifdef QUOTA2 742 if (!fs->fs_ronly) { 743 error = ffs_quota2_mount(mp); 744 if (error) { 745 DPRINTF("ffs_quota2_mount returned %d", error); 746 return error; 747 } 748 } 749#endif 750 751 if ((mp->mnt_flag & MNT_DISCARD) && !(ump->um_discarddata)) 752 ump->um_discarddata = ffs_discard_init(devvp, fs); 753 754 if (args->fspec == NULL) 755 return 0; 756 } 757 758 (void)strncpy(fs->fs_fsmnt, mp->mnt_stat.f_mntonname, 759 sizeof(fs->fs_fsmnt)); 760 761 fs->fs_flags &= ~FS_DOSOFTDEP; 762 763 if ((fs->fs_ronly && (fs->fs_clean & FS_ISCLEAN) == 0) || 764 (!fs->fs_ronly && (fs->fs_clean & FS_WASCLEAN) == 0)) { 765 printf("%s: file system not clean (fs_clean=%#x); " 766 "please fsck(8)\n", mp->mnt_stat.f_mntfromname, 767 fs->fs_clean); 768 } 769 770 if (fs->fs_fmod != 0) { 771 int err; 772 773 KASSERT(!fs->fs_ronly); 774 775 if (fs->fs_clean & FS_WASCLEAN) 776 fs->fs_time = time_second; 777 fs->fs_fmod = 0; 778 err = UFS_WAPBL_BEGIN(mp); 779 if (err == 0) { 780 (void) ffs_cgupdate(ump, MNT_WAIT); 781 UFS_WAPBL_END(mp); 782 } 783 } 784 if ((mp->mnt_flag & MNT_SOFTDEP) != 0) { 785 printf("%s: `-o softdep' is no longer supported, " 786 "consider `-o log'\n", mp->mnt_stat.f_mntfromname); 787 mp->mnt_flag &= ~MNT_SOFTDEP; 788 } 789 790 return (error); 791 792fail: 793 vrele(devvp); 794 return (error); 795} 796 797/* 798 * Reload all incore data for a filesystem (used after running fsck on 799 * the root filesystem and finding things to fix). The filesystem must 800 * be mounted read-only. 801 * 802 * Things to do to update the mount: 803 * 1) invalidate all cached meta-data. 804 * 2) re-read superblock from disk. 805 * 3) re-read summary information from disk. 806 * 4) invalidate all inactive vnodes. 807 * 5) invalidate all cached file data. 808 * 6) re-read inode data for all active vnodes. 809 */ 810int 811ffs_reload(struct mount *mp, kauth_cred_t cred, struct lwp *l) 812{ 813 struct vnode *vp, *devvp; 814 struct inode *ip; 815 void *space; 816 struct buf *bp; 817 struct fs *fs, *newfs; 818 int i, bsize, blks, error; 819 int32_t *lp, fs_sbsize; 820 struct ufsmount *ump; 821 daddr_t sblockloc; 822 struct vnode_iterator *marker; 823 824 if ((mp->mnt_flag & MNT_RDONLY) == 0) 825 return (EINVAL); 826 827 ump = VFSTOUFS(mp); 828 829 /* 830 * Step 1: invalidate all cached meta-data. 831 */ 832 devvp = ump->um_devvp; 833 vn_lock(devvp, LK_EXCLUSIVE | LK_RETRY); 834 error = vinvalbuf(devvp, 0, cred, l, 0, 0); 835 VOP_UNLOCK(devvp); 836 if (error) 837 panic("%s: dirty1", __func__); 838 839 /* 840 * Step 2: re-read superblock from disk. XXX: We don't handle 841 * possibility that superblock moved. Which implies that we don't 842 * want its size to change either. 843 */ 844 fs = ump->um_fs; 845 fs_sbsize = fs->fs_sbsize; 846 error = bread(devvp, fs->fs_sblockloc / DEV_BSIZE, fs_sbsize, 847 0, &bp); 848 if (error) 849 return (error); 850 newfs = kmem_alloc(fs_sbsize, KM_SLEEP); 851 memcpy(newfs, bp->b_data, fs_sbsize); 852 853#ifdef FFS_EI 854 if (ump->um_flags & UFS_NEEDSWAP) { 855 ffs_sb_swap((struct fs *)bp->b_data, newfs); 856 newfs->fs_flags |= FS_SWAPPED; 857 } else 858#endif 859 newfs->fs_flags &= ~FS_SWAPPED; 860 861 brelse(bp, 0); 862 863 /* Allow converting from UFS2 to UFS2EA but not vice versa. */ 864 if (newfs->fs_magic == FS_UFS2EA_MAGIC) { 865 ump->um_flags |= UFS_EA; 866 newfs->fs_magic = FS_UFS2_MAGIC; 867 } else { 868 if ((ump->um_flags & UFS_EA) != 0) 869 return EINVAL; 870 } 871 872 if ((newfs->fs_magic != FS_UFS1_MAGIC) && 873 (newfs->fs_magic != FS_UFS2_MAGIC)) { 874 kmem_free(newfs, fs_sbsize); 875 return (EIO); /* XXX needs translation */ 876 } 877 if (!ffs_superblock_validate(newfs)) { 878 kmem_free(newfs, fs_sbsize); 879 return (EINVAL); 880 } 881 882 /* 883 * The current implementation doesn't handle the possibility that 884 * these values may have changed. 885 */ 886 if ((newfs->fs_sbsize != fs_sbsize) || 887 (newfs->fs_cssize != fs->fs_cssize) || 888 (newfs->fs_contigsumsize != fs->fs_contigsumsize) || 889 (newfs->fs_ncg != fs->fs_ncg)) { 890 kmem_free(newfs, fs_sbsize); 891 return (EINVAL); 892 } 893 894 /* Store off old fs_sblockloc for fs_oldfscompat_read. */ 895 sblockloc = fs->fs_sblockloc; 896 /* 897 * Copy pointer fields back into superblock before copying in XXX 898 * new superblock. These should really be in the ufsmount. XXX 899 * Note that important parameters (eg fs_ncg) are unchanged. 900 */ 901 newfs->fs_csp = fs->fs_csp; 902 newfs->fs_maxcluster = fs->fs_maxcluster; 903 newfs->fs_contigdirs = fs->fs_contigdirs; 904 newfs->fs_ronly = fs->fs_ronly; 905 newfs->fs_active = fs->fs_active; 906 memcpy(fs, newfs, (u_int)fs_sbsize); 907 kmem_free(newfs, fs_sbsize); 908 909 /* 910 * Recheck for Apple UFS filesystem. 911 */ 912 ump->um_flags &= ~UFS_ISAPPLEUFS; 913 if (ffs_is_appleufs(devvp, fs)) { 914#ifdef APPLE_UFS 915 ump->um_flags |= UFS_ISAPPLEUFS; 916#else 917 DPRINTF("AppleUFS not supported"); 918 return (EIO); /* XXX: really? */ 919#endif 920 } 921 922 if (UFS_MPISAPPLEUFS(ump)) { 923 /* see comment about NeXT below */ 924 ump->um_maxsymlinklen = APPLEUFS_MAXSYMLINKLEN; 925 ump->um_dirblksiz = APPLEUFS_DIRBLKSIZ; 926 mp->mnt_iflag |= IMNT_DTYPE; 927 } else { 928 ump->um_maxsymlinklen = fs->fs_maxsymlinklen; 929 ump->um_dirblksiz = UFS_DIRBLKSIZ; 930 if (ump->um_maxsymlinklen > 0) 931 mp->mnt_iflag |= IMNT_DTYPE; 932 else 933 mp->mnt_iflag &= ~IMNT_DTYPE; 934 } 935 ffs_oldfscompat_read(fs, ump, sblockloc); 936 937 mutex_enter(&ump->um_lock); 938 ump->um_maxfilesize = fs->fs_maxfilesize; 939 if (fs->fs_flags & ~(FS_KNOWN_FLAGS | FS_INTERNAL)) { 940 uprintf("%s: unknown ufs flags: 0x%08"PRIx32"%s\n", 941 mp->mnt_stat.f_mntonname, fs->fs_flags, 942 (mp->mnt_flag & MNT_FORCE) ? "" : ", not mounting"); 943 if ((mp->mnt_flag & MNT_FORCE) == 0) { 944 mutex_exit(&ump->um_lock); 945 return (EINVAL); 946 } 947 } 948 949 if (fs->fs_pendingblocks != 0 || fs->fs_pendinginodes != 0) { 950 fs->fs_pendingblocks = 0; 951 fs->fs_pendinginodes = 0; 952 } 953 mutex_exit(&ump->um_lock); 954 955 ffs_statvfs(mp, &mp->mnt_stat); 956 /* 957 * Step 3: re-read summary information from disk. 958 */ 959 blks = howmany(fs->fs_cssize, fs->fs_fsize); 960 space = fs->fs_csp; 961 for (i = 0; i < blks; i += fs->fs_frag) { 962 bsize = fs->fs_bsize; 963 if (i + fs->fs_frag > blks) 964 bsize = (blks - i) * fs->fs_fsize; 965 error = bread(devvp, FFS_FSBTODB(fs, fs->fs_csaddr + i), bsize, 966 0, &bp); 967 if (error) { 968 return (error); 969 } 970#ifdef FFS_EI 971 if (UFS_FSNEEDSWAP(fs)) 972 ffs_csum_swap((struct csum *)bp->b_data, 973 (struct csum *)space, bsize); 974 else 975#endif 976 memcpy(space, bp->b_data, (size_t)bsize); 977 space = (char *)space + bsize; 978 brelse(bp, 0); 979 } 980 /* 981 * We no longer know anything about clusters per cylinder group. 982 */ 983 if (fs->fs_contigsumsize > 0) { 984 lp = fs->fs_maxcluster; 985 for (i = 0; i < fs->fs_ncg; i++) 986 *lp++ = fs->fs_contigsumsize; 987 } 988 989 vfs_vnode_iterator_init(mp, &marker); 990 while ((vp = vfs_vnode_iterator_next(marker, NULL, NULL))) { 991 /* 992 * Step 4: invalidate all inactive vnodes. 993 */ 994 if (vrecycle(vp)) 995 continue; 996 /* 997 * Step 5: invalidate all cached file data. 998 */ 999 if (vn_lock(vp, LK_EXCLUSIVE)) { 1000 vrele(vp); 1001 continue; 1002 } 1003 if (vinvalbuf(vp, 0, cred, l, 0, 0)) 1004 panic("%s: dirty2", __func__); 1005 /* 1006 * Step 6: re-read inode data for all active vnodes. 1007 */ 1008 ip = VTOI(vp); 1009 error = bread(devvp, FFS_FSBTODB(fs, ino_to_fsba(fs, ip->i_number)), 1010 (int)fs->fs_bsize, 0, &bp); 1011 if (error) { 1012 vput(vp); 1013 break; 1014 } 1015 ffs_load_inode(bp, ip, fs, ip->i_number); 1016 brelse(bp, 0); 1017 vput(vp); 1018 } 1019 vfs_vnode_iterator_destroy(marker); 1020 return (error); 1021} 1022 1023/* 1024 * Possible superblock locations ordered from most to least likely. 1025 */ 1026static const int sblock_try[] = SBLOCKSEARCH; 1027 1028 1029static int 1030ffs_superblock_validate(struct fs *fs) 1031{ 1032 int32_t i, fs_bshift = 0, fs_fshift = 0, fs_fragshift = 0, fs_frag; 1033 int32_t fs_inopb; 1034 1035 /* Check the superblock size */ 1036 if (fs->fs_sbsize > SBLOCKSIZE || fs->fs_sbsize < sizeof(struct fs)) 1037 return 0; 1038 1039 /* Check the file system blocksize */ 1040 if (fs->fs_bsize > MAXBSIZE || fs->fs_bsize < MINBSIZE) 1041 return 0; 1042 if (!powerof2(fs->fs_bsize)) 1043 return 0; 1044 1045 /* Check the size of frag blocks */ 1046 if (!powerof2(fs->fs_fsize)) 1047 return 0; 1048 if (fs->fs_fsize == 0) 1049 return 0; 1050 1051 /* 1052 * XXX: these values are just zero-checked to prevent obvious 1053 * bugs. We need more strict checks. 1054 */ 1055 if (fs->fs_size == 0 && fs->fs_old_size == 0) 1056 return 0; 1057 if (fs->fs_cssize == 0) 1058 return 0; 1059 if (fs->fs_ipg == 0) 1060 return 0; 1061 if (fs->fs_fpg == 0) 1062 return 0; 1063 if (fs->fs_ncg == 0) 1064 return 0; 1065 if (fs->fs_maxbpg == 0) 1066 return 0; 1067 1068 /* Check the number of inodes per block */ 1069 if (fs->fs_magic == FS_UFS1_MAGIC) 1070 fs_inopb = fs->fs_bsize / sizeof(struct ufs1_dinode); 1071 else /* fs->fs_magic == FS_UFS2_MAGIC */ 1072 fs_inopb = fs->fs_bsize / sizeof(struct ufs2_dinode); 1073 if (fs->fs_inopb != fs_inopb) 1074 return 0; 1075 1076 /* Block size cannot be smaller than fragment size */ 1077 if (fs->fs_bsize < fs->fs_fsize) 1078 return 0; 1079 1080 /* Compute fs_bshift and ensure it is consistent */ 1081 for (i = fs->fs_bsize; i > 1; i >>= 1) 1082 fs_bshift++; 1083 if (fs->fs_bshift != fs_bshift) 1084 return 0; 1085 1086 /* Compute fs_fshift and ensure it is consistent */ 1087 for (i = fs->fs_fsize; i > 1; i >>= 1) 1088 fs_fshift++; 1089 if (fs->fs_fshift != fs_fshift) 1090 return 0; 1091 1092 /* Compute fs_fragshift and ensure it is consistent */ 1093 for (i = fs->fs_frag; i > 1; i >>= 1) 1094 fs_fragshift++; 1095 if (fs->fs_fragshift != fs_fragshift) 1096 return 0; 1097 1098 /* Check the masks */ 1099 if (fs->fs_bmask != ~(fs->fs_bsize - 1)) 1100 return 0; 1101 if (fs->fs_fmask != ~(fs->fs_fsize - 1)) 1102 return 0; 1103 1104 /* 1105 * Now that the shifts and masks are sanitized, we can use the ffs_ API. 1106 */ 1107 1108 /* Check the number of frag blocks */ 1109 if ((fs_frag = ffs_numfrags(fs, fs->fs_bsize)) > MAXFRAG) 1110 return 0; 1111 if (fs->fs_frag != fs_frag) 1112 return 0; 1113 1114 /* Check the size of cylinder groups */ 1115 if ((fs->fs_cgsize < sizeof(struct cg)) || 1116 (fs->fs_cgsize > fs->fs_bsize)) 1117 return 0; 1118 1119 return 1; 1120} 1121 1122static int 1123ffs_is_appleufs(struct vnode *devvp, struct fs *fs) 1124{ 1125 struct dkwedge_info dkw; 1126 int ret = 0; 1127 1128 /* 1129 * First check to see if this is tagged as an Apple UFS filesystem 1130 * in the disklabel. 1131 */ 1132 if (getdiskinfo(devvp, &dkw) == 0 && 1133 strcmp(dkw.dkw_ptype, DKW_PTYPE_APPLEUFS) == 0) 1134 ret = 1; 1135#ifdef APPLE_UFS 1136 else { 1137 struct appleufslabel *applefs; 1138 struct buf *bp; 1139 daddr_t blkno = APPLEUFS_LABEL_OFFSET / DEV_BSIZE; 1140 int error; 1141 1142 /* 1143 * Manually look for an Apple UFS label, and if a valid one 1144 * is found, then treat it like an Apple UFS filesystem anyway. 1145 */ 1146 error = bread(devvp, blkno, APPLEUFS_LABEL_SIZE, 0, &bp); 1147 if (error) { 1148 DPRINTF("bread@0x%jx returned %d", (intmax_t)blkno, error); 1149 return 0; 1150 } 1151 applefs = (struct appleufslabel *)bp->b_data; 1152 error = ffs_appleufs_validate(fs->fs_fsmnt, applefs, NULL); 1153 if (error == 0) 1154 ret = 1; 1155 brelse(bp, 0); 1156 } 1157#endif 1158 1159 return ret; 1160} 1161 1162/* 1163 * Common code for mount and mountroot 1164 */ 1165int 1166ffs_mountfs(struct vnode *devvp, struct mount *mp, struct lwp *l) 1167{ 1168 struct ufsmount *ump = NULL; 1169 struct buf *bp = NULL; 1170 struct fs *fs = NULL; 1171 dev_t dev; 1172 void *space; 1173 daddr_t sblockloc = 0; 1174 int blks, fstype = 0; 1175 int error, i, bsize, ronly, bset = 0; 1176#ifdef FFS_EI 1177 int needswap = 0; /* keep gcc happy */ 1178#endif 1179 int32_t *lp; 1180 kauth_cred_t cred; 1181 u_int32_t allocsbsize, fs_sbsize = 0; 1182 1183 dev = devvp->v_rdev; 1184 cred = l ? l->l_cred : NOCRED; 1185 1186 /* Flush out any old buffers remaining from a previous use. */ 1187 vn_lock(devvp, LK_EXCLUSIVE | LK_RETRY); 1188 error = vinvalbuf(devvp, V_SAVE, cred, l, 0, 0); 1189 VOP_UNLOCK(devvp); 1190 if (error) { 1191 DPRINTF("vinvalbuf returned %d", error); 1192 return error; 1193 } 1194 1195 ronly = (mp->mnt_flag & MNT_RDONLY) != 0; 1196 1197 ump = kmem_zalloc(sizeof(*ump), KM_SLEEP); 1198 mutex_init(&ump->um_lock, MUTEX_DEFAULT, IPL_NONE); 1199 error = ffs_snapshot_init(ump); 1200 if (error) { 1201 DPRINTF("ffs_snapshot_init returned %d", error); 1202 goto out; 1203 } 1204 ump->um_ops = &ffs_ufsops; 1205 1206#ifdef WAPBL 1207 sbagain: 1208#endif 1209 /* 1210 * Try reading the superblock in each of its possible locations. 1211 */ 1212 for (i = 0; ; i++) { 1213 daddr_t fs_sblockloc; 1214 1215 if (bp != NULL) { 1216 brelse(bp, BC_NOCACHE); 1217 bp = NULL; 1218 } 1219 if (sblock_try[i] == -1) { 1220 DPRINTF("no superblock found"); 1221 error = EINVAL; 1222 fs = NULL; 1223 goto out; 1224 } 1225 1226 error = bread(devvp, sblock_try[i] / DEV_BSIZE, SBLOCKSIZE, 1227 0, &bp); 1228 if (error) { 1229 DPRINTF("bread@0x%x returned %d", 1230 sblock_try[i] / DEV_BSIZE, error); 1231 fs = NULL; 1232 goto out; 1233 } 1234 fs = (struct fs *)bp->b_data; 1235 1236 sblockloc = sblock_try[i]; 1237 DPRINTF("fs_magic 0x%x", fs->fs_magic); 1238 1239 /* 1240 * Swap: here, we swap fs->fs_sbsize in order to get the correct 1241 * size to read the superblock. Once read, we swap the whole 1242 * superblock structure. 1243 */ 1244 if (fs->fs_magic == FS_UFS2EA_MAGIC) { 1245 ump->um_flags |= UFS_EA; 1246 fs->fs_magic = FS_UFS2_MAGIC; 1247 } else if (fs->fs_magic == FS_UFS2EA_MAGIC_SWAPPED) { 1248 ump->um_flags |= UFS_EA; 1249 fs->fs_magic = FS_UFS2_MAGIC_SWAPPED; 1250 } 1251 if (fs->fs_magic == FS_UFS1_MAGIC) { 1252 fs_sbsize = fs->fs_sbsize; 1253 fstype = UFS1; 1254#ifdef FFS_EI 1255 needswap = 0; 1256 } else if (fs->fs_magic == FS_UFS1_MAGIC_SWAPPED) { 1257 fs_sbsize = bswap32(fs->fs_sbsize); 1258 fstype = UFS1; 1259 needswap = 1; 1260#endif 1261 } else if (fs->fs_magic == FS_UFS2_MAGIC) { 1262 fs_sbsize = fs->fs_sbsize; 1263 fstype = UFS2; 1264#ifdef FFS_EI 1265 needswap = 0; 1266 } else if (fs->fs_magic == FS_UFS2_MAGIC_SWAPPED) { 1267 fs_sbsize = bswap32(fs->fs_sbsize); 1268 fstype = UFS2; 1269 needswap = 1; 1270#endif 1271 } else 1272 continue; 1273 1274 /* fs->fs_sblockloc isn't defined for old filesystems */ 1275 if (fstype == UFS1 && !(fs->fs_old_flags & FS_FLAGS_UPDATED)) { 1276 if (sblockloc == SBLOCK_UFS2) 1277 /* 1278 * This is likely to be the first alternate 1279 * in a filesystem with 64k blocks. 1280 * Don't use it. 1281 */ 1282 continue; 1283 fs_sblockloc = sblockloc; 1284 } else { 1285 fs_sblockloc = fs->fs_sblockloc; 1286#ifdef FFS_EI 1287 if (needswap) 1288 fs_sblockloc = bswap64(fs_sblockloc); 1289#endif 1290 } 1291 1292 /* Check we haven't found an alternate superblock */ 1293 if (fs_sblockloc != sblockloc) 1294 continue; 1295 1296 /* Check the superblock size */ 1297 if (fs_sbsize > SBLOCKSIZE || fs_sbsize < sizeof(struct fs)) 1298 continue; 1299 fs = kmem_alloc((u_long)fs_sbsize, KM_SLEEP); 1300 memcpy(fs, bp->b_data, fs_sbsize); 1301 1302 /* Swap the whole superblock structure, if necessary. */ 1303#ifdef FFS_EI 1304 if (needswap) { 1305 ffs_sb_swap((struct fs*)bp->b_data, fs); 1306 fs->fs_flags |= FS_SWAPPED; 1307 } else 1308#endif 1309 fs->fs_flags &= ~FS_SWAPPED; 1310 1311 /* 1312 * Now that everything is swapped, the superblock is ready to 1313 * be sanitized. 1314 */ 1315 if (!ffs_superblock_validate(fs)) { 1316 kmem_free(fs, fs_sbsize); 1317 continue; 1318 } 1319 1320 /* Ok seems to be a good superblock */ 1321 break; 1322 } 1323 1324 ump->um_fs = fs; 1325 1326#ifdef WAPBL 1327 if ((mp->mnt_wapbl_replay == 0) && (fs->fs_flags & FS_DOWAPBL)) { 1328 error = ffs_wapbl_replay_start(mp, fs, devvp); 1329 if (error && (mp->mnt_flag & MNT_FORCE) == 0) { 1330 DPRINTF("ffs_wapbl_replay_start returned %d", error); 1331 goto out; 1332 } 1333 if (!error) { 1334 if (!ronly) { 1335 /* XXX fsmnt may be stale. */ 1336 printf("%s: replaying log to disk\n", 1337 fs->fs_fsmnt); 1338 error = wapbl_replay_write(mp->mnt_wapbl_replay, 1339 devvp); 1340 if (error) { 1341 DPRINTF("wapbl_replay_write returned %d", 1342 error); 1343 goto out; 1344 } 1345 wapbl_replay_stop(mp->mnt_wapbl_replay); 1346 fs->fs_clean = FS_WASCLEAN; 1347 } else { 1348 /* XXX fsmnt may be stale */ 1349 printf("%s: replaying log to memory\n", 1350 fs->fs_fsmnt); 1351 } 1352 1353 /* Force a re-read of the superblock */ 1354 brelse(bp, BC_INVAL); 1355 bp = NULL; 1356 kmem_free(fs, fs_sbsize); 1357 fs = NULL; 1358 goto sbagain; 1359 } 1360 } 1361#else /* !WAPBL */ 1362 if ((fs->fs_flags & FS_DOWAPBL) && (mp->mnt_flag & MNT_FORCE) == 0) { 1363 error = EPERM; 1364 DPRINTF("no force %d", error); 1365 goto out; 1366 } 1367#endif /* !WAPBL */ 1368 1369 ffs_oldfscompat_read(fs, ump, sblockloc); 1370 ump->um_maxfilesize = fs->fs_maxfilesize; 1371 1372 if (fs->fs_flags & ~(FS_KNOWN_FLAGS | FS_INTERNAL)) { 1373 uprintf("%s: unknown ufs flags: 0x%08"PRIx32"%s\n", 1374 mp->mnt_stat.f_mntonname, fs->fs_flags, 1375 (mp->mnt_flag & MNT_FORCE) ? "" : ", not mounting"); 1376 if ((mp->mnt_flag & MNT_FORCE) == 0) { 1377 error = EINVAL; 1378 DPRINTF("no force %d", error); 1379 goto out; 1380 } 1381 } 1382 1383 fs->fs_fmod = 0; 1384 if (fs->fs_pendingblocks != 0 || fs->fs_pendinginodes != 0) { 1385 fs->fs_pendingblocks = 0; 1386 fs->fs_pendinginodes = 0; 1387 } 1388 1389 ump->um_fstype = fstype; 1390 if (fs->fs_sbsize < SBLOCKSIZE) 1391 brelse(bp, BC_INVAL); 1392 else 1393 brelse(bp, 0); 1394 bp = NULL; 1395 1396 if (ffs_is_appleufs(devvp, fs)) { 1397#ifdef APPLE_UFS 1398 ump->um_flags |= UFS_ISAPPLEUFS; 1399#else 1400 DPRINTF("AppleUFS not supported"); 1401 error = EINVAL; 1402 goto out; 1403#endif 1404 } 1405 1406#if 0 1407/* 1408 * XXX This code changes the behaviour of mounting dirty filesystems, to 1409 * XXX require "mount -f ..." to mount them. This doesn't match what 1410 * XXX mount(8) describes and is disabled for now. 1411 */ 1412 /* 1413 * If the file system is not clean, don't allow it to be mounted 1414 * unless MNT_FORCE is specified. (Note: MNT_FORCE is always set 1415 * for the root file system.) 1416 */ 1417 if (fs->fs_flags & FS_DOWAPBL) { 1418 /* 1419 * wapbl normally expects to be FS_WASCLEAN when the FS_DOWAPBL 1420 * bit is set, although there's a window in unmount where it 1421 * could be FS_ISCLEAN 1422 */ 1423 if ((mp->mnt_flag & MNT_FORCE) == 0 && 1424 (fs->fs_clean & (FS_WASCLEAN | FS_ISCLEAN)) == 0) { 1425 error = EPERM; 1426 goto out; 1427 } 1428 } else 1429 if ((fs->fs_clean & FS_ISCLEAN) == 0 && 1430 (mp->mnt_flag & MNT_FORCE) == 0) { 1431 error = EPERM; 1432 goto out; 1433 } 1434#endif 1435 1436 /* 1437 * Verify that we can access the last block in the fs 1438 * if we're mounting read/write. 1439 */ 1440 if (!ronly) { 1441 error = bread(devvp, FFS_FSBTODB(fs, fs->fs_size - 1), 1442 fs->fs_fsize, 0, &bp); 1443 if (error) { 1444 DPRINTF("bread@0x%jx returned %d", 1445 (intmax_t)FFS_FSBTODB(fs, fs->fs_size - 1), 1446 error); 1447 bset = BC_INVAL; 1448 goto out; 1449 } 1450 if (bp->b_bcount != fs->fs_fsize) { 1451 DPRINTF("bcount %x != fsize %x", bp->b_bcount, 1452 fs->fs_fsize); 1453 error = EINVAL; 1454 bset = BC_INVAL; 1455 goto out; 1456 } 1457 brelse(bp, BC_INVAL); 1458 bp = NULL; 1459 } 1460 1461 fs->fs_ronly = ronly; 1462 /* Don't bump fs_clean if we're replaying journal */ 1463 if (!((fs->fs_flags & FS_DOWAPBL) && (fs->fs_clean & FS_WASCLEAN))) { 1464 if (ronly == 0) { 1465 fs->fs_clean = 1466 fs->fs_clean == FS_ISCLEAN ? FS_WASCLEAN : 0; 1467 fs->fs_fmod = 1; 1468 } 1469 } 1470 1471 bsize = fs->fs_cssize; 1472 blks = howmany(bsize, fs->fs_fsize); 1473 if (fs->fs_contigsumsize > 0) 1474 bsize += fs->fs_ncg * sizeof(int32_t); 1475 bsize += fs->fs_ncg * sizeof(*fs->fs_contigdirs); 1476 allocsbsize = bsize; 1477 space = kmem_alloc((u_long)allocsbsize, KM_SLEEP); 1478 fs->fs_csp = space; 1479 1480 for (i = 0; i < blks; i += fs->fs_frag) { 1481 bsize = fs->fs_bsize; 1482 if (i + fs->fs_frag > blks) 1483 bsize = (blks - i) * fs->fs_fsize; 1484 error = bread(devvp, FFS_FSBTODB(fs, fs->fs_csaddr + i), bsize, 1485 0, &bp); 1486 if (error) { 1487 DPRINTF("bread@0x%jx %d", 1488 (intmax_t)FFS_FSBTODB(fs, fs->fs_csaddr + i), 1489 error); 1490 goto out1; 1491 } 1492#ifdef FFS_EI 1493 if (needswap) 1494 ffs_csum_swap((struct csum *)bp->b_data, 1495 (struct csum *)space, bsize); 1496 else 1497#endif 1498 memcpy(space, bp->b_data, (u_int)bsize); 1499 1500 space = (char *)space + bsize; 1501 brelse(bp, 0); 1502 bp = NULL; 1503 } 1504 if (fs->fs_contigsumsize > 0) { 1505 fs->fs_maxcluster = lp = space; 1506 for (i = 0; i < fs->fs_ncg; i++) 1507 *lp++ = fs->fs_contigsumsize; 1508 space = lp; 1509 } 1510 bsize = fs->fs_ncg * sizeof(*fs->fs_contigdirs); 1511 fs->fs_contigdirs = space; 1512 space = (char *)space + bsize; 1513 memset(fs->fs_contigdirs, 0, bsize); 1514 1515 /* Compatibility for old filesystems - XXX */ 1516 if (fs->fs_avgfilesize <= 0) 1517 fs->fs_avgfilesize = AVFILESIZ; 1518 if (fs->fs_avgfpdir <= 0) 1519 fs->fs_avgfpdir = AFPDIR; 1520 fs->fs_active = NULL; 1521 1522 mp->mnt_data = ump; 1523 mp->mnt_stat.f_fsidx.__fsid_val[0] = (long)dev; 1524 mp->mnt_stat.f_fsidx.__fsid_val[1] = makefstype(MOUNT_FFS); 1525 mp->mnt_stat.f_fsid = mp->mnt_stat.f_fsidx.__fsid_val[0]; 1526 mp->mnt_stat.f_namemax = FFS_MAXNAMLEN; 1527 if (UFS_MPISAPPLEUFS(ump)) { 1528 /* NeXT used to keep short symlinks in the inode even 1529 * when using FS_42INODEFMT. In that case fs->fs_maxsymlinklen 1530 * is probably -1, but we still need to be able to identify 1531 * short symlinks. 1532 */ 1533 ump->um_maxsymlinklen = APPLEUFS_MAXSYMLINKLEN; 1534 ump->um_dirblksiz = APPLEUFS_DIRBLKSIZ; 1535 mp->mnt_iflag |= IMNT_DTYPE; 1536 } else { 1537 ump->um_maxsymlinklen = fs->fs_maxsymlinklen; 1538 ump->um_dirblksiz = UFS_DIRBLKSIZ; 1539 if (ump->um_maxsymlinklen > 0) 1540 mp->mnt_iflag |= IMNT_DTYPE; 1541 else 1542 mp->mnt_iflag &= ~IMNT_DTYPE; 1543 } 1544 mp->mnt_fs_bshift = fs->fs_bshift; 1545 mp->mnt_dev_bshift = DEV_BSHIFT; /* XXX */ 1546 mp->mnt_flag |= MNT_LOCAL; 1547 mp->mnt_iflag |= IMNT_MPSAFE | IMNT_CAN_RWTORO | IMNT_SHRLOOKUP | 1548 IMNT_NCLOOKUP; 1549#ifdef FFS_EI 1550 if (needswap) 1551 ump->um_flags |= UFS_NEEDSWAP; 1552#endif 1553 error = ffs_acls(mp, fs->fs_flags); 1554 if (error) 1555 goto out1; 1556 ump->um_mountp = mp; 1557 ump->um_dev = dev; 1558 ump->um_devvp = devvp; 1559 ump->um_nindir = fs->fs_nindir; 1560 ump->um_lognindir = ffs(fs->fs_nindir) - 1; 1561 ump->um_bptrtodb = fs->fs_fshift - DEV_BSHIFT; 1562 ump->um_seqinc = fs->fs_frag; 1563 for (i = 0; i < MAXQUOTAS; i++) 1564 ump->um_quotas[i] = NULLVP; 1565 spec_node_setmountedfs(devvp, mp); 1566 if (ronly == 0 && fs->fs_snapinum[0] != 0) 1567 ffs_snapshot_mount(mp); 1568#ifdef WAPBL 1569 if (!ronly) { 1570 KDASSERT(fs->fs_ronly == 0); 1571 /* 1572 * ffs_wapbl_start() needs mp->mnt_stat initialised if it 1573 * needs to create a new log file in-filesystem. 1574 */ 1575 error = ffs_statvfs(mp, &mp->mnt_stat); 1576 if (error) { 1577 DPRINTF("ffs_statvfs returned %d", error); 1578 goto out1; 1579 } 1580 1581 error = ffs_wapbl_start(mp); 1582 if (error) { 1583 DPRINTF("ffs_wapbl_start returned %d", error); 1584 goto out1; 1585 } 1586 } 1587#endif /* WAPBL */ 1588 if (ronly == 0) { 1589#ifdef QUOTA2 1590 error = ffs_quota2_mount(mp); 1591 if (error) { 1592 DPRINTF("ffs_quota2_mount returned %d", error); 1593 goto out1; 1594 } 1595#else 1596 if (fs->fs_flags & FS_DOQUOTA2) { 1597 ump->um_flags |= UFS_QUOTA2; 1598 uprintf("%s: options QUOTA2 not enabled%s\n", 1599 mp->mnt_stat.f_mntonname, 1600 (mp->mnt_flag & MNT_FORCE) ? "" : ", not mounting"); 1601 if ((mp->mnt_flag & MNT_FORCE) == 0) { 1602 error = EINVAL; 1603 DPRINTF("quota disabled %d", error); 1604 goto out1; 1605 } 1606 } 1607#endif 1608 } 1609 1610 if (mp->mnt_flag & MNT_DISCARD) 1611 ump->um_discarddata = ffs_discard_init(devvp, fs); 1612 1613 return (0); 1614out1: 1615 kmem_free(fs->fs_csp, allocsbsize); 1616out: 1617#ifdef WAPBL 1618 if (mp->mnt_wapbl_replay) { 1619 wapbl_replay_stop(mp->mnt_wapbl_replay); 1620 wapbl_replay_free(mp->mnt_wapbl_replay); 1621 mp->mnt_wapbl_replay = 0; 1622 } 1623#endif 1624 1625 if (fs) 1626 kmem_free(fs, fs->fs_sbsize); 1627 spec_node_setmountedfs(devvp, NULL); 1628 if (bp) 1629 brelse(bp, bset); 1630 if (ump) { 1631 if (ump->um_oldfscompat) 1632 kmem_free(ump->um_oldfscompat, 512 + 3*sizeof(int32_t)); 1633 mutex_destroy(&ump->um_lock); 1634 kmem_free(ump, sizeof(*ump)); 1635 mp->mnt_data = NULL; 1636 } 1637 return (error); 1638} 1639 1640/* 1641 * Sanity checks for loading old filesystem superblocks. 1642 * See ffs_oldfscompat_write below for unwound actions. 1643 * 1644 * XXX - Parts get retired eventually. 1645 * Unfortunately new bits get added. 1646 */ 1647static void 1648ffs_oldfscompat_read(struct fs *fs, struct ufsmount *ump, daddr_t sblockloc) 1649{ 1650 off_t maxfilesize; 1651 int32_t *extrasave; 1652 1653 if ((fs->fs_magic != FS_UFS1_MAGIC) || 1654 (fs->fs_old_flags & FS_FLAGS_UPDATED)) 1655 return; 1656 1657 if (!ump->um_oldfscompat) 1658 ump->um_oldfscompat = kmem_alloc(512 + 3*sizeof(int32_t), 1659 KM_SLEEP); 1660 1661 memcpy(ump->um_oldfscompat, &fs->fs_old_postbl_start, 512); 1662 extrasave = ump->um_oldfscompat; 1663 extrasave += 512/sizeof(int32_t); 1664 extrasave[0] = fs->fs_old_npsect; 1665 extrasave[1] = fs->fs_old_interleave; 1666 extrasave[2] = fs->fs_old_trackskew; 1667 1668 /* These fields will be overwritten by their 1669 * original values in fs_oldfscompat_write, so it is harmless 1670 * to modify them here. 1671 */ 1672 fs->fs_cstotal.cs_ndir = fs->fs_old_cstotal.cs_ndir; 1673 fs->fs_cstotal.cs_nbfree = fs->fs_old_cstotal.cs_nbfree; 1674 fs->fs_cstotal.cs_nifree = fs->fs_old_cstotal.cs_nifree; 1675 fs->fs_cstotal.cs_nffree = fs->fs_old_cstotal.cs_nffree; 1676 1677 fs->fs_maxbsize = fs->fs_bsize; 1678 fs->fs_time = fs->fs_old_time; 1679 fs->fs_size = fs->fs_old_size; 1680 fs->fs_dsize = fs->fs_old_dsize; 1681 fs->fs_csaddr = fs->fs_old_csaddr; 1682 fs->fs_sblockloc = sblockloc; 1683 1684 fs->fs_flags = fs->fs_old_flags | (fs->fs_flags & FS_INTERNAL); 1685 1686 if (fs->fs_old_postblformat == FS_42POSTBLFMT) { 1687 fs->fs_old_nrpos = 8; 1688 fs->fs_old_npsect = fs->fs_old_nsect; 1689 fs->fs_old_interleave = 1; 1690 fs->fs_old_trackskew = 0; 1691 } 1692 1693 if (fs->fs_magic == FS_UFS1_MAGIC && 1694 fs->fs_old_inodefmt < FS_44INODEFMT) { 1695 fs->fs_maxfilesize = (u_quad_t) 1LL << 39; 1696 fs->fs_qbmask = ~fs->fs_bmask; 1697 fs->fs_qfmask = ~fs->fs_fmask; 1698 } 1699 1700 maxfilesize = (u_int64_t)0x80000000 * fs->fs_bsize - 1; 1701 if (fs->fs_maxfilesize > maxfilesize) 1702 fs->fs_maxfilesize = maxfilesize; 1703 1704 /* Compatibility for old filesystems */ 1705 if (fs->fs_avgfilesize <= 0) 1706 fs->fs_avgfilesize = AVFILESIZ; 1707 if (fs->fs_avgfpdir <= 0) 1708 fs->fs_avgfpdir = AFPDIR; 1709 1710#if 0 1711 if (bigcgs) { 1712 fs->fs_save_cgsize = fs->fs_cgsize; 1713 fs->fs_cgsize = fs->fs_bsize; 1714 } 1715#endif 1716} 1717 1718/* 1719 * Unwinding superblock updates for old filesystems. 1720 * See ffs_oldfscompat_read above for details. 1721 * 1722 * XXX - Parts get retired eventually. 1723 * Unfortunately new bits get added. 1724 */ 1725static void 1726ffs_oldfscompat_write(struct fs *fs, struct ufsmount *ump) 1727{ 1728 int32_t *extrasave; 1729 1730 if ((fs->fs_magic != FS_UFS1_MAGIC) || 1731 (fs->fs_old_flags & FS_FLAGS_UPDATED)) 1732 return; 1733 1734 fs->fs_old_time = fs->fs_time; 1735 fs->fs_old_cstotal.cs_ndir = fs->fs_cstotal.cs_ndir; 1736 fs->fs_old_cstotal.cs_nbfree = fs->fs_cstotal.cs_nbfree; 1737 fs->fs_old_cstotal.cs_nifree = fs->fs_cstotal.cs_nifree; 1738 fs->fs_old_cstotal.cs_nffree = fs->fs_cstotal.cs_nffree; 1739 fs->fs_old_flags = fs->fs_flags; 1740 1741#if 0 1742 if (bigcgs) { 1743 fs->fs_cgsize = fs->fs_save_cgsize; 1744 } 1745#endif 1746 1747 memcpy(&fs->fs_old_postbl_start, ump->um_oldfscompat, 512); 1748 extrasave = ump->um_oldfscompat; 1749 extrasave += 512/sizeof(int32_t); 1750 fs->fs_old_npsect = extrasave[0]; 1751 fs->fs_old_interleave = extrasave[1]; 1752 fs->fs_old_trackskew = extrasave[2]; 1753 1754} 1755 1756/* 1757 * unmount vfs operation 1758 */ 1759int 1760ffs_unmount(struct mount *mp, int mntflags) 1761{ 1762 struct lwp *l = curlwp; 1763 struct ufsmount *ump = VFSTOUFS(mp); 1764 struct fs *fs = ump->um_fs; 1765 int error, flags; 1766 u_int32_t bsize; 1767#ifdef WAPBL 1768 extern int doforce; 1769#endif 1770 1771 if (ump->um_discarddata) { 1772 ffs_discard_finish(ump->um_discarddata, mntflags); 1773 ump->um_discarddata = NULL; 1774 } 1775 1776 flags = 0; 1777 if (mntflags & MNT_FORCE) 1778 flags |= FORCECLOSE; 1779 if ((error = ffs_flushfiles(mp, flags, l)) != 0) 1780 return (error); 1781 error = UFS_WAPBL_BEGIN(mp); 1782 if (error == 0) 1783 if (fs->fs_ronly == 0 && 1784 ffs_cgupdate(ump, MNT_WAIT) == 0 && 1785 fs->fs_clean & FS_WASCLEAN) { 1786 fs->fs_clean = FS_ISCLEAN; 1787 fs->fs_fmod = 0; 1788 (void) ffs_sbupdate(ump, MNT_WAIT); 1789 } 1790 if (error == 0) 1791 UFS_WAPBL_END(mp); 1792#ifdef WAPBL 1793 KASSERT(!(mp->mnt_wapbl_replay && mp->mnt_wapbl)); 1794 if (mp->mnt_wapbl_replay) { 1795 KDASSERT(fs->fs_ronly); 1796 wapbl_replay_stop(mp->mnt_wapbl_replay); 1797 wapbl_replay_free(mp->mnt_wapbl_replay); 1798 mp->mnt_wapbl_replay = 0; 1799 } 1800 error = ffs_wapbl_stop(mp, doforce && (mntflags & MNT_FORCE)); 1801 if (error) { 1802 return error; 1803 } 1804#endif /* WAPBL */ 1805 1806 if (ump->um_devvp->v_type != VBAD) 1807 spec_node_setmountedfs(ump->um_devvp, NULL); 1808 vn_lock(ump->um_devvp, LK_EXCLUSIVE | LK_RETRY); 1809 (void)VOP_CLOSE(ump->um_devvp, fs->fs_ronly ? FREAD : FREAD | FWRITE, 1810 NOCRED); 1811 vput(ump->um_devvp); 1812 1813 bsize = fs->fs_cssize; 1814 if (fs->fs_contigsumsize > 0) 1815 bsize += fs->fs_ncg * sizeof(int32_t); 1816 bsize += fs->fs_ncg * sizeof(*fs->fs_contigdirs); 1817 kmem_free(fs->fs_csp, bsize); 1818 1819 kmem_free(fs, fs->fs_sbsize); 1820 if (ump->um_oldfscompat != NULL) 1821 kmem_free(ump->um_oldfscompat, 512 + 3*sizeof(int32_t)); 1822 mutex_destroy(&ump->um_lock); 1823 ffs_snapshot_fini(ump); 1824 kmem_free(ump, sizeof(*ump)); 1825 mp->mnt_data = NULL; 1826 mp->mnt_flag &= ~MNT_LOCAL; 1827 return (0); 1828} 1829 1830/* 1831 * Flush out all the files in a filesystem. 1832 */ 1833int 1834ffs_flushfiles(struct mount *mp, int flags, struct lwp *l) 1835{ 1836 extern int doforce; 1837 struct ufsmount *ump; 1838 int error; 1839 1840 if (!doforce) 1841 flags &= ~FORCECLOSE; 1842 ump = VFSTOUFS(mp); 1843#ifdef QUOTA 1844 if ((error = quota1_umount(mp, flags)) != 0) 1845 return (error); 1846#endif 1847#ifdef QUOTA2 1848 if ((error = quota2_umount(mp, flags)) != 0) 1849 return (error); 1850#endif 1851#ifdef UFS_EXTATTR 1852 if (ump->um_fstype == UFS1) { 1853 if (ump->um_extattr.uepm_flags & UFS_EXTATTR_UEPM_STARTED) 1854 ufs_extattr_stop(mp, l); 1855 if (ump->um_extattr.uepm_flags & UFS_EXTATTR_UEPM_INITIALIZED) 1856 ufs_extattr_uepm_destroy(&ump->um_extattr); 1857 mp->mnt_flag &= ~MNT_EXTATTR; 1858 } 1859#endif 1860 if ((error = vflush(mp, 0, SKIPSYSTEM | flags)) != 0) 1861 return (error); 1862 ffs_snapshot_unmount(mp); 1863 /* 1864 * Flush all the files. 1865 */ 1866 error = vflush(mp, NULLVP, flags); 1867 if (error) 1868 return (error); 1869 /* 1870 * Flush filesystem metadata. 1871 */ 1872 vn_lock(ump->um_devvp, LK_EXCLUSIVE | LK_RETRY); 1873 error = VOP_FSYNC(ump->um_devvp, l->l_cred, FSYNC_WAIT, 0, 0); 1874 VOP_UNLOCK(ump->um_devvp); 1875 if (flags & FORCECLOSE) /* XXXDBJ */ 1876 error = 0; 1877 1878#ifdef WAPBL 1879 if (error) 1880 return error; 1881 if (mp->mnt_wapbl) { 1882 error = wapbl_flush(mp->mnt_wapbl, 1); 1883 if (flags & FORCECLOSE) 1884 error = 0; 1885 } 1886#endif 1887 1888 return (error); 1889} 1890 1891/* 1892 * Get file system statistics. 1893 */ 1894int 1895ffs_statvfs(struct mount *mp, struct statvfs *sbp) 1896{ 1897 struct ufsmount *ump; 1898 struct fs *fs; 1899 1900 ump = VFSTOUFS(mp); 1901 fs = ump->um_fs; 1902 mutex_enter(&ump->um_lock); 1903 sbp->f_bsize = fs->fs_bsize; 1904 sbp->f_frsize = fs->fs_fsize; 1905 sbp->f_iosize = fs->fs_bsize; 1906 sbp->f_blocks = fs->fs_dsize; 1907 sbp->f_bfree = ffs_blkstofrags(fs, fs->fs_cstotal.cs_nbfree) + 1908 fs->fs_cstotal.cs_nffree + FFS_DBTOFSB(fs, fs->fs_pendingblocks); 1909 sbp->f_bresvd = ((u_int64_t) fs->fs_dsize * (u_int64_t) 1910 fs->fs_minfree) / (u_int64_t) 100; 1911 if (sbp->f_bfree > sbp->f_bresvd) 1912 sbp->f_bavail = sbp->f_bfree - sbp->f_bresvd; 1913 else 1914 sbp->f_bavail = 0; 1915 sbp->f_files = fs->fs_ncg * fs->fs_ipg - UFS_ROOTINO; 1916 sbp->f_ffree = fs->fs_cstotal.cs_nifree + fs->fs_pendinginodes; 1917 sbp->f_favail = sbp->f_ffree; 1918 sbp->f_fresvd = 0; 1919 mutex_exit(&ump->um_lock); 1920 copy_statvfs_info(sbp, mp); 1921 1922 return (0); 1923} 1924 1925struct ffs_sync_ctx { 1926 int waitfor; 1927}; 1928 1929static bool 1930ffs_sync_selector(void *cl, struct vnode *vp) 1931{ 1932 struct ffs_sync_ctx *c = cl; 1933 struct inode *ip; 1934 1935 KASSERT(mutex_owned(vp->v_interlock)); 1936 1937 ip = VTOI(vp); 1938 /* 1939 * Skip the vnode/inode if inaccessible. 1940 */ 1941 if (ip == NULL || vp->v_type == VNON) 1942 return false; 1943 1944 /* 1945 * We deliberately update inode times here. This will 1946 * prevent a massive queue of updates accumulating, only 1947 * to be handled by a call to unmount. 1948 * 1949 * XXX It would be better to have the syncer trickle these 1950 * out. Adjustment needed to allow registering vnodes for 1951 * sync when the vnode is clean, but the inode dirty. Or 1952 * have ufs itself trickle out inode updates. 1953 * 1954 * If doing a lazy sync, we don't care about metadata or 1955 * data updates, because they are handled by each vnode's 1956 * synclist entry. In this case we are only interested in 1957 * writing back modified inodes. 1958 */ 1959 if ((ip->i_flag & (IN_ACCESS | IN_CHANGE | IN_UPDATE | 1960 IN_MODIFY | IN_MODIFIED | IN_ACCESSED)) == 0 && 1961 (c->waitfor == MNT_LAZY || (LIST_EMPTY(&vp->v_dirtyblkhd) && 1962 (vp->v_iflag & VI_ONWORKLST) == 0))) 1963 return false; 1964 1965 return true; 1966} 1967 1968/* 1969 * Go through the disk queues to initiate sandbagged IO; 1970 * go through the inodes to write those that have been modified; 1971 * initiate the writing of the super block if it has been modified. 1972 * 1973 * Note: we are always called with the filesystem marked `MPBUSY'. 1974 */ 1975int 1976ffs_sync(struct mount *mp, int waitfor, kauth_cred_t cred) 1977{ 1978 struct vnode *vp; 1979 struct ufsmount *ump = VFSTOUFS(mp); 1980 struct fs *fs; 1981 struct vnode_iterator *marker; 1982 int error, allerror = 0; 1983 struct ffs_sync_ctx ctx; 1984 1985 fs = ump->um_fs; 1986 if (fs->fs_fmod != 0 && fs->fs_ronly != 0) { /* XXX */ 1987 panic("%s: rofs mod, fs=%s", __func__, fs->fs_fsmnt); 1988 } 1989 1990 /* 1991 * Write back each (modified) inode. 1992 */ 1993 vfs_vnode_iterator_init(mp, &marker); 1994 1995 ctx.waitfor = waitfor; 1996 while ((vp = vfs_vnode_iterator_next(marker, ffs_sync_selector, &ctx))) 1997 { 1998 error = vn_lock(vp, 1999 LK_EXCLUSIVE | (waitfor == MNT_LAZY ? LK_NOWAIT : 0)); 2000 if (error) { 2001 vrele(vp); 2002 continue; 2003 } 2004 if (waitfor == MNT_LAZY) { 2005 error = UFS_WAPBL_BEGIN(vp->v_mount); 2006 if (!error) { 2007 error = ffs_update(vp, NULL, NULL, 2008 UPDATE_CLOSE); 2009 UFS_WAPBL_END(vp->v_mount); 2010 } 2011 } else { 2012 error = VOP_FSYNC(vp, cred, FSYNC_NOLOG | 2013 (waitfor == MNT_WAIT ? FSYNC_WAIT : 0), 0, 0); 2014 } 2015 if (error) 2016 allerror = error; 2017 vput(vp); 2018 } 2019 vfs_vnode_iterator_destroy(marker); 2020 2021 /* 2022 * Force stale file system control information to be flushed. 2023 */ 2024 if (waitfor != MNT_LAZY) { 2025 bool need_devvp_fsync; 2026 2027 mutex_enter(ump->um_devvp->v_interlock); 2028 need_devvp_fsync = (ump->um_devvp->v_numoutput > 0 || 2029 !LIST_EMPTY(&ump->um_devvp->v_dirtyblkhd)); 2030 mutex_exit(ump->um_devvp->v_interlock); 2031 if (need_devvp_fsync) { 2032 int flags = FSYNC_NOLOG; 2033 2034 if (waitfor == MNT_WAIT) 2035 flags |= FSYNC_WAIT; 2036 2037 vn_lock(ump->um_devvp, LK_EXCLUSIVE | LK_RETRY); 2038 if ((error = VOP_FSYNC(ump->um_devvp, cred, flags, 0, 2039 0)) != 0) 2040 allerror = error; 2041 VOP_UNLOCK(ump->um_devvp); 2042 } 2043 } 2044#if defined(QUOTA) || defined(QUOTA2) 2045 qsync(mp); 2046#endif 2047 /* 2048 * Write back modified superblock. 2049 */ 2050 if (fs->fs_fmod != 0) { 2051 fs->fs_fmod = 0; 2052 fs->fs_time = time_second; 2053 error = UFS_WAPBL_BEGIN(mp); 2054 if (error) 2055 allerror = error; 2056 else { 2057 if ((error = ffs_cgupdate(ump, waitfor))) 2058 allerror = error; 2059 UFS_WAPBL_END(mp); 2060 } 2061 } 2062 2063#ifdef WAPBL 2064 if (mp->mnt_wapbl) { 2065 error = wapbl_flush(mp->mnt_wapbl, (waitfor == MNT_WAIT)); 2066 if (error) 2067 allerror = error; 2068 } 2069#endif 2070 2071 return (allerror); 2072} 2073 2074/* 2075 * Load inode from disk and initialize vnode. 2076 */ 2077static int 2078ffs_init_vnode(struct ufsmount *ump, struct vnode *vp, ino_t ino) 2079{ 2080 struct fs *fs; 2081 struct inode *ip; 2082 struct buf *bp; 2083 int error; 2084 2085 fs = ump->um_fs; 2086 2087 /* Read in the disk contents for the inode. */ 2088 error = bread(ump->um_devvp, FFS_FSBTODB(fs, ino_to_fsba(fs, ino)), 2089 (int)fs->fs_bsize, 0, &bp); 2090 if (error) 2091 return error; 2092 2093 /* Allocate and initialize inode. */ 2094 ip = pool_cache_get(ffs_inode_cache, PR_WAITOK); 2095 memset(ip, 0, sizeof(struct inode)); 2096 ip->i_ump = ump; 2097 ip->i_fs = fs; 2098 ip->i_dev = ump->um_dev; 2099 ip->i_number = ino; 2100 if (ump->um_fstype == UFS1) 2101 ip->i_din.ffs1_din = pool_cache_get(ffs_dinode1_cache, 2102 PR_WAITOK); 2103 else 2104 ip->i_din.ffs2_din = pool_cache_get(ffs_dinode2_cache, 2105 PR_WAITOK); 2106 ffs_load_inode(bp, ip, fs, ino); 2107 brelse(bp, 0); 2108 ip->i_vnode = vp; 2109#if defined(QUOTA) || defined(QUOTA2) 2110 ufsquota_init(ip); 2111#endif 2112 2113 /* Initialise vnode with this inode. */ 2114 vp->v_tag = VT_UFS; 2115 vp->v_op = ffs_vnodeop_p; 2116 vp->v_data = ip; 2117 2118 /* Initialize genfs node. */ 2119 genfs_node_init(vp, &ffs_genfsops); 2120 2121 return 0; 2122} 2123 2124/* 2125 * Undo ffs_init_vnode(). 2126 */ 2127static void 2128ffs_deinit_vnode(struct ufsmount *ump, struct vnode *vp) 2129{ 2130 struct inode *ip = VTOI(vp); 2131 2132 genfs_node_destroy(vp); 2133 vp->v_data = NULL; 2134 2135 if (ump->um_fstype == UFS1) 2136 pool_cache_put(ffs_dinode1_cache, ip->i_din.ffs1_din); 2137 else 2138 pool_cache_put(ffs_dinode2_cache, ip->i_din.ffs2_din); 2139 pool_cache_put(ffs_inode_cache, ip); 2140} 2141 2142/* 2143 * Read an inode from disk and initialize this vnode / inode pair. 2144 * Caller assures no other thread will try to load this inode. 2145 */ 2146int 2147ffs_loadvnode(struct mount *mp, struct vnode *vp, 2148 const void *key, size_t key_len, const void **new_key) 2149{ 2150 ino_t ino; 2151 struct fs *fs; 2152 struct inode *ip; 2153 struct ufsmount *ump; 2154 int error; 2155 2156 KASSERT(key_len == sizeof(ino)); 2157 memcpy(&ino, key, key_len); 2158 ump = VFSTOUFS(mp); 2159 fs = ump->um_fs; 2160 2161 error = ffs_init_vnode(ump, vp, ino); 2162 if (error) 2163 return error; 2164 2165 ip = VTOI(vp); 2166 if (ip->i_mode == 0) { 2167 ffs_deinit_vnode(ump, vp); 2168 2169 return ENOENT; 2170 } 2171 2172 /* Initialize the vnode from the inode. */ 2173 ufs_vinit(mp, ffs_specop_p, ffs_fifoop_p, &vp); 2174 2175 /* Finish inode initialization. */ 2176 ip->i_devvp = ump->um_devvp; 2177 vref(ip->i_devvp); 2178 2179 /* 2180 * Ensure that uid and gid are correct. This is a temporary 2181 * fix until fsck has been changed to do the update. 2182 */ 2183 2184 if (fs->fs_magic == FS_UFS1_MAGIC && /* XXX */ 2185 fs->fs_old_inodefmt < FS_44INODEFMT) { /* XXX */ 2186 ip->i_uid = ip->i_ffs1_ouid; /* XXX */ 2187 ip->i_gid = ip->i_ffs1_ogid; /* XXX */ 2188 } /* XXX */ 2189 uvm_vnp_setsize(vp, ip->i_size); 2190 cache_enter_id(vp, ip->i_mode, ip->i_uid, ip->i_gid, !HAS_ACLS(ip)); 2191 *new_key = &ip->i_number; 2192 return 0; 2193} 2194 2195/* 2196 * Create a new inode on disk and initialize this vnode / inode pair. 2197 */ 2198int 2199ffs_newvnode(struct mount *mp, struct vnode *dvp, struct vnode *vp, 2200 struct vattr *vap, kauth_cred_t cred, void *extra, 2201 size_t *key_len, const void **new_key) 2202{ 2203 ino_t ino; 2204 struct fs *fs; 2205 struct inode *ip; 2206 struct timespec ts; 2207 struct ufsmount *ump; 2208 int error, mode; 2209 2210 KASSERT(dvp->v_mount == mp); 2211 KASSERT(vap->va_type != VNON); 2212 2213 *key_len = sizeof(ino); 2214 ump = VFSTOUFS(mp); 2215 fs = ump->um_fs; 2216 mode = MAKEIMODE(vap->va_type, vap->va_mode); 2217 2218 /* Allocate fresh inode. */ 2219 error = ffs_valloc(dvp, mode, cred, &ino); 2220 if (error) 2221 return error; 2222 2223 /* Attach inode to vnode. */ 2224 error = ffs_init_vnode(ump, vp, ino); 2225 if (error) { 2226 if (UFS_WAPBL_BEGIN(mp) == 0) { 2227 ffs_vfree(dvp, ino, mode); 2228 UFS_WAPBL_END(mp); 2229 } 2230 return error; 2231 } 2232 2233 ip = VTOI(vp); 2234 if (ip->i_mode) { 2235 panic("%s: dup alloc ino=%" PRId64 " on %s: mode %o/%o " 2236 "gen %x/%x size %" PRIx64 " blocks %" PRIx64, 2237 __func__, ino, fs->fs_fsmnt, DIP(ip, mode), ip->i_mode, 2238 DIP(ip, gen), ip->i_gen, DIP(ip, size), DIP(ip, blocks)); 2239 } 2240 if (DIP(ip, size) || DIP(ip, blocks)) { 2241 printf("%s: ino=%" PRId64 " on %s: " 2242 "gen %x/%x has non zero blocks %" PRIx64 " or size %" 2243 PRIx64 "\n", 2244 __func__, ino, fs->fs_fsmnt, DIP(ip, gen), ip->i_gen, 2245 DIP(ip, blocks), DIP(ip, size)); 2246 if ((ip)->i_ump->um_fstype == UFS1) 2247 panic("%s: dirty filesystem?", __func__); 2248 DIP_ASSIGN(ip, blocks, 0); 2249 DIP_ASSIGN(ip, size, 0); 2250 } 2251 2252 /* Set uid / gid. */ 2253 if (cred == NOCRED || cred == FSCRED) { 2254 ip->i_gid = 0; 2255 ip->i_uid = 0; 2256 } else { 2257 ip->i_gid = VTOI(dvp)->i_gid; 2258 ip->i_uid = kauth_cred_geteuid(cred); 2259 } 2260 DIP_ASSIGN(ip, gid, ip->i_gid); 2261 DIP_ASSIGN(ip, uid, ip->i_uid); 2262 2263#if defined(QUOTA) || defined(QUOTA2) 2264 error = UFS_WAPBL_BEGIN(mp); 2265 if (error) { 2266 ffs_deinit_vnode(ump, vp); 2267 2268 return error; 2269 } 2270 error = chkiq(ip, 1, cred, 0); 2271 if (error) { 2272 ffs_vfree(dvp, ino, mode); 2273 UFS_WAPBL_END(mp); 2274 ffs_deinit_vnode(ump, vp); 2275 2276 return error; 2277 } 2278 UFS_WAPBL_END(mp); 2279#endif 2280 2281 /* Set type and finalize. */ 2282 ip->i_flags = 0; 2283 DIP_ASSIGN(ip, flags, 0); 2284 ip->i_mode = mode; 2285 DIP_ASSIGN(ip, mode, mode); 2286 if (vap->va_rdev != VNOVAL) { 2287 /* 2288 * Want to be able to use this to make badblock 2289 * inodes, so don't truncate the dev number. 2290 */ 2291 if (ump->um_fstype == UFS1) 2292 ip->i_ffs1_rdev = ufs_rw32(vap->va_rdev, 2293 UFS_MPNEEDSWAP(ump)); 2294 else 2295 ip->i_ffs2_rdev = ufs_rw64(vap->va_rdev, 2296 UFS_MPNEEDSWAP(ump)); 2297 } 2298 ufs_vinit(mp, ffs_specop_p, ffs_fifoop_p, &vp); 2299 ip->i_devvp = ump->um_devvp; 2300 vref(ip->i_devvp); 2301 2302 /* Set up a new generation number for this inode. */ 2303 ip->i_gen++; 2304 DIP_ASSIGN(ip, gen, ip->i_gen); 2305 if (fs->fs_magic == FS_UFS2_MAGIC) { 2306 vfs_timestamp(&ts); 2307 ip->i_ffs2_birthtime = ts.tv_sec; 2308 ip->i_ffs2_birthnsec = ts.tv_nsec; 2309 } 2310 2311 uvm_vnp_setsize(vp, ip->i_size); 2312 cache_enter_id(vp, ip->i_mode, ip->i_uid, ip->i_gid, !HAS_ACLS(ip)); 2313 *new_key = &ip->i_number; 2314 return 0; 2315} 2316 2317/* 2318 * File handle to vnode 2319 * 2320 * Have to be really careful about stale file handles: 2321 * - check that the inode number is valid 2322 * - call ffs_vget() to get the locked inode 2323 * - check for an unallocated inode (i_mode == 0) 2324 * - check that the given client host has export rights and return 2325 * those rights via. exflagsp and credanonp 2326 */ 2327int 2328ffs_fhtovp(struct mount *mp, struct fid *fhp, int lktype, struct vnode **vpp) 2329{ 2330 struct ufid ufh; 2331 int error; 2332 2333 if (fhp->fid_len != sizeof(struct ufid)) 2334 return EINVAL; 2335 2336 memcpy(&ufh, fhp, sizeof(ufh)); 2337 if ((error = ffs_checkrange(mp, ufh.ufid_ino)) != 0) 2338 return error; 2339 2340 return (ufs_fhtovp(mp, &ufh, lktype, vpp)); 2341} 2342 2343/* 2344 * Vnode pointer to File handle 2345 */ 2346/* ARGSUSED */ 2347int 2348ffs_vptofh(struct vnode *vp, struct fid *fhp, size_t *fh_size) 2349{ 2350 struct inode *ip; 2351 struct ufid ufh; 2352 2353 if (*fh_size < sizeof(struct ufid)) { 2354 *fh_size = sizeof(struct ufid); 2355 return E2BIG; 2356 } 2357 ip = VTOI(vp); 2358 *fh_size = sizeof(struct ufid); 2359 memset(&ufh, 0, sizeof(ufh)); 2360 ufh.ufid_len = sizeof(struct ufid); 2361 ufh.ufid_ino = ip->i_number; 2362 ufh.ufid_gen = ip->i_gen; 2363 memcpy(fhp, &ufh, sizeof(ufh)); 2364 return (0); 2365} 2366 2367void 2368ffs_init(void) 2369{ 2370 if (ffs_initcount++ > 0) 2371 return; 2372 2373 ffs_inode_cache = pool_cache_init(sizeof(struct inode), 0, 0, 0, 2374 "ffsino", NULL, IPL_NONE, NULL, NULL, NULL); 2375 ffs_dinode1_cache = pool_cache_init(sizeof(struct ufs1_dinode), 0, 0, 0, 2376 "ffsdino1", NULL, IPL_NONE, NULL, NULL, NULL); 2377 ffs_dinode2_cache = pool_cache_init(sizeof(struct ufs2_dinode), 0, 0, 0, 2378 "ffsdino2", NULL, IPL_NONE, NULL, NULL, NULL); 2379 ufs_init(); 2380} 2381 2382void 2383ffs_reinit(void) 2384{ 2385 ufs_reinit(); 2386} 2387 2388void 2389ffs_done(void) 2390{ 2391 if (--ffs_initcount > 0) 2392 return; 2393 2394 ufs_done(); 2395 pool_cache_destroy(ffs_dinode2_cache); 2396 pool_cache_destroy(ffs_dinode1_cache); 2397 pool_cache_destroy(ffs_inode_cache); 2398} 2399 2400/* 2401 * Write a superblock and associated information back to disk. 2402 */ 2403int 2404ffs_sbupdate(struct ufsmount *mp, int waitfor) 2405{ 2406 struct fs *fs = mp->um_fs; 2407 struct buf *bp; 2408 int error; 2409 u_int32_t saveflag; 2410 2411 error = ffs_getblk(mp->um_devvp, 2412 fs->fs_sblockloc / DEV_BSIZE, FFS_NOBLK, 2413 fs->fs_sbsize, false, &bp); 2414 if (error) 2415 return error; 2416 saveflag = fs->fs_flags & FS_INTERNAL; 2417 fs->fs_flags &= ~FS_INTERNAL; 2418 2419 memcpy(bp->b_data, fs, fs->fs_sbsize); 2420 2421 ffs_oldfscompat_write((struct fs *)bp->b_data, mp); 2422 if (mp->um_flags & UFS_EA) { 2423 struct fs *bfs = (struct fs *)bp->b_data; 2424 KASSERT(bfs->fs_magic == FS_UFS2_MAGIC); 2425 bfs->fs_magic = FS_UFS2EA_MAGIC; 2426 } 2427#ifdef FFS_EI 2428 if (mp->um_flags & UFS_NEEDSWAP) 2429 ffs_sb_swap((struct fs *)bp->b_data, (struct fs *)bp->b_data); 2430#endif 2431 fs->fs_flags |= saveflag; 2432 2433 if (waitfor == MNT_WAIT) 2434 error = bwrite(bp); 2435 else 2436 bawrite(bp); 2437 return (error); 2438} 2439 2440int 2441ffs_cgupdate(struct ufsmount *mp, int waitfor) 2442{ 2443 struct fs *fs = mp->um_fs; 2444 struct buf *bp; 2445 int blks; 2446 void *space; 2447 int i, size, error = 0, allerror = 0; 2448 2449 UFS_WAPBL_JLOCK_ASSERT(mp->um_mountp); 2450 2451 allerror = ffs_sbupdate(mp, waitfor); 2452 blks = howmany(fs->fs_cssize, fs->fs_fsize); 2453 space = fs->fs_csp; 2454 for (i = 0; i < blks; i += fs->fs_frag) { 2455 size = fs->fs_bsize; 2456 if (i + fs->fs_frag > blks) 2457 size = (blks - i) * fs->fs_fsize; 2458 error = ffs_getblk(mp->um_devvp, FFS_FSBTODB(fs, fs->fs_csaddr + i), 2459 FFS_NOBLK, size, false, &bp); 2460 if (error) 2461 break; 2462#ifdef FFS_EI 2463 if (mp->um_flags & UFS_NEEDSWAP) 2464 ffs_csum_swap((struct csum*)space, 2465 (struct csum*)bp->b_data, size); 2466 else 2467#endif 2468 memcpy(bp->b_data, space, (u_int)size); 2469 space = (char *)space + size; 2470 if (waitfor == MNT_WAIT) 2471 error = bwrite(bp); 2472 else 2473 bawrite(bp); 2474 } 2475 if (!allerror && error) 2476 allerror = error; 2477 return (allerror); 2478} 2479 2480int 2481ffs_extattrctl(struct mount *mp, int cmd, struct vnode *vp, 2482 int attrnamespace, const char *attrname) 2483{ 2484#ifdef UFS_EXTATTR 2485 /* 2486 * File-backed extended attributes are only supported on UFS1. 2487 * UFS2 has native extended attributes. 2488 */ 2489 if (VFSTOUFS(mp)->um_fstype == UFS1) 2490 return (ufs_extattrctl(mp, cmd, vp, attrnamespace, attrname)); 2491#endif 2492 return (vfs_stdextattrctl(mp, cmd, vp, attrnamespace, attrname)); 2493} 2494 2495/* 2496 * Synch vnode for a mounted file system. 2497 */ 2498static int 2499ffs_vfs_fsync(vnode_t *vp, int flags) 2500{ 2501 int error, i, pflags; 2502#ifdef WAPBL 2503 struct mount *mp; 2504#endif 2505 2506 KASSERT(vp->v_type == VBLK); 2507 KASSERT(spec_node_getmountedfs(vp) != NULL); 2508 2509 /* 2510 * Flush all dirty data associated with the vnode. 2511 */ 2512 pflags = PGO_ALLPAGES | PGO_CLEANIT; 2513 if ((flags & FSYNC_WAIT) != 0) 2514 pflags |= PGO_SYNCIO; 2515 rw_enter(vp->v_uobj.vmobjlock, RW_WRITER); 2516 error = VOP_PUTPAGES(vp, 0, 0, pflags); 2517 if (error) 2518 return error; 2519 2520#ifdef WAPBL 2521 mp = spec_node_getmountedfs(vp); 2522 if (mp && mp->mnt_wapbl) { 2523 /* 2524 * Don't bother writing out metadata if the syncer is 2525 * making the request. We will let the sync vnode 2526 * write it out in a single burst through a call to 2527 * VFS_SYNC(). 2528 */ 2529 if ((flags & (FSYNC_DATAONLY | FSYNC_LAZY | FSYNC_NOLOG)) != 0) 2530 return 0; 2531 2532 /* 2533 * Don't flush the log if the vnode being flushed 2534 * contains no dirty buffers that could be in the log. 2535 */ 2536 if (!LIST_EMPTY(&vp->v_dirtyblkhd)) { 2537 error = wapbl_flush(mp->mnt_wapbl, 0); 2538 if (error) 2539 return error; 2540 } 2541 2542 if ((flags & FSYNC_WAIT) != 0) { 2543 mutex_enter(vp->v_interlock); 2544 while (vp->v_numoutput) 2545 cv_wait(&vp->v_cv, vp->v_interlock); 2546 mutex_exit(vp->v_interlock); 2547 } 2548 2549 return 0; 2550 } 2551#endif /* WAPBL */ 2552 2553 error = vflushbuf(vp, flags); 2554 if (error == 0 && (flags & FSYNC_CACHE) != 0) { 2555 i = 1; 2556 (void)VOP_IOCTL(vp, DIOCCACHESYNC, &i, FWRITE, 2557 kauth_cred_get()); 2558 } 2559 2560 return error; 2561} 2562