1 /* $OpenBSD: ext2fs_vfsops.c,v 1.118 2023/03/08 04:43:09 guenther Exp $ */ 2 /* $NetBSD: ext2fs_vfsops.c,v 1.1 1997/06/11 09:34:07 bouyer Exp $ */ 3 4 /* 5 * Copyright (c) 1997 Manuel Bouyer. 6 * Copyright (c) 1989, 1991, 1993, 1994 7 * The Regents of the University of California. All rights reserved. 8 * 9 * Redistribution and use in source and binary forms, with or without 10 * modification, are permitted provided that the following conditions 11 * are met: 12 * 1. Redistributions of source code must retain the above copyright 13 * notice, this list of conditions and the following disclaimer. 14 * 2. Redistributions in binary form must reproduce the above copyright 15 * notice, this list of conditions and the following disclaimer in the 16 * documentation and/or other materials provided with the distribution. 17 * 3. 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.14 (Berkeley) 11/28/94 34 * Modified for ext2fs by Manuel Bouyer. 35 */ 36 37 #include <sys/param.h> 38 #include <sys/systm.h> 39 #include <sys/namei.h> 40 #include <sys/proc.h> 41 #include <sys/kernel.h> 42 #include <sys/vnode.h> 43 #include <sys/socket.h> 44 #include <sys/mount.h> 45 #include <sys/buf.h> 46 #include <sys/disk.h> 47 #include <sys/mbuf.h> 48 #include <sys/fcntl.h> 49 #include <sys/disklabel.h> 50 #include <sys/ioctl.h> 51 #include <sys/errno.h> 52 #include <sys/malloc.h> 53 #include <sys/pool.h> 54 #include <sys/lock.h> 55 #include <sys/dkio.h> 56 #include <sys/specdev.h> 57 58 #include <ufs/ufs/quota.h> 59 #include <ufs/ufs/ufsmount.h> 60 #include <ufs/ufs/inode.h> 61 #include <ufs/ufs/dir.h> 62 #include <ufs/ufs/ufs_extern.h> 63 64 #include <ufs/ext2fs/ext2fs.h> 65 #include <ufs/ext2fs/ext2fs_extern.h> 66 67 extern struct lock ufs_hashlock; 68 69 int ext2fs_sbupdate(struct ufsmount *, int); 70 static int e2fs_sbcheck(struct ext2fs *, int); 71 72 const struct vfsops ext2fs_vfsops = { 73 .vfs_mount = ext2fs_mount, 74 .vfs_start = ufs_start, 75 .vfs_unmount = ext2fs_unmount, 76 .vfs_root = ufs_root, 77 .vfs_quotactl = ufs_quotactl, 78 .vfs_statfs = ext2fs_statfs, 79 .vfs_sync = ext2fs_sync, 80 .vfs_vget = ext2fs_vget, 81 .vfs_fhtovp = ext2fs_fhtovp, 82 .vfs_vptofh = ext2fs_vptofh, 83 .vfs_init = ext2fs_init, 84 .vfs_sysctl = ext2fs_sysctl, 85 .vfs_checkexp = ufs_check_export, 86 }; 87 88 struct pool ext2fs_inode_pool; 89 struct pool ext2fs_dinode_pool; 90 91 extern u_long ext2gennumber; 92 93 int 94 ext2fs_init(struct vfsconf *vfsp) 95 { 96 pool_init(&ext2fs_inode_pool, sizeof(struct inode), 0, 97 IPL_NONE, PR_WAITOK, "ext2inopl", NULL); 98 pool_init(&ext2fs_dinode_pool, sizeof(struct ext2fs_dinode), 0, 99 IPL_NONE, PR_WAITOK, "ext2dinopl", NULL); 100 101 return (ufs_init(vfsp)); 102 } 103 104 /* 105 * Called by main() when ext2fs is going to be mounted as root. 106 * 107 * Name is updated by mount(8) after booting. 108 */ 109 #define ROOTNAME "root_device" 110 111 int 112 ext2fs_mountroot(void) 113 { 114 struct m_ext2fs *fs; 115 struct mount *mp; 116 struct proc *p = curproc; /* XXX */ 117 struct ufsmount *ump; 118 int error; 119 120 /* 121 * Get vnodes for swapdev and rootdev. 122 */ 123 if (bdevvp(swapdev, &swapdev_vp) || bdevvp(rootdev, &rootvp)) 124 panic("ext2fs_mountroot: can't setup bdevvp's"); 125 126 if ((error = vfs_rootmountalloc("ext2fs", "root_device", &mp)) != 0) { 127 vrele(rootvp); 128 return (error); 129 } 130 131 if ((error = ext2fs_mountfs(rootvp, mp, p)) != 0) { 132 vfs_unbusy(mp); 133 vfs_mount_free(mp); 134 vrele(rootvp); 135 return (error); 136 } 137 138 TAILQ_INSERT_TAIL(&mountlist, mp, mnt_list); 139 ump = VFSTOUFS(mp); 140 fs = ump->um_e2fs; 141 memset(fs->e2fs_fsmnt, 0, sizeof(fs->e2fs_fsmnt)); 142 strlcpy(fs->e2fs_fsmnt, mp->mnt_stat.f_mntonname, sizeof(fs->e2fs_fsmnt)); 143 if (fs->e2fs.e2fs_rev > E2FS_REV0) { 144 memset(fs->e2fs.e2fs_fsmnt, 0, sizeof(fs->e2fs.e2fs_fsmnt)); 145 strlcpy(fs->e2fs.e2fs_fsmnt, mp->mnt_stat.f_mntonname, 146 sizeof(fs->e2fs.e2fs_fsmnt)); 147 } 148 (void)ext2fs_statfs(mp, &mp->mnt_stat, p); 149 vfs_unbusy(mp); 150 inittodr(fs->e2fs.e2fs_wtime); 151 return (0); 152 } 153 154 /* 155 * VFS Operations. 156 * 157 * mount system call 158 */ 159 int 160 ext2fs_mount(struct mount *mp, const char *path, void *data, 161 struct nameidata *ndp, struct proc *p) 162 { 163 struct vnode *devvp; 164 struct ufs_args *args = data; 165 struct ufsmount *ump = NULL; 166 struct m_ext2fs *fs; 167 char fname[MNAMELEN]; 168 char fspec[MNAMELEN]; 169 int error, flags; 170 171 /* 172 * If updating, check whether changing from read-only to 173 * read/write; if there is no device name, that's all we do. 174 */ 175 if (mp->mnt_flag & MNT_UPDATE) { 176 ump = VFSTOUFS(mp); 177 fs = ump->um_e2fs; 178 if (fs->e2fs_ronly == 0 && (mp->mnt_flag & MNT_RDONLY)) { 179 flags = WRITECLOSE; 180 if (mp->mnt_flag & MNT_FORCE) 181 flags |= FORCECLOSE; 182 error = ext2fs_flushfiles(mp, flags, p); 183 if (error == 0 && 184 ext2fs_cgupdate(ump, MNT_WAIT) == 0 && 185 (fs->e2fs.e2fs_state & E2FS_ERRORS) == 0) { 186 fs->e2fs.e2fs_state = E2FS_ISCLEAN; 187 (void)ext2fs_sbupdate(ump, MNT_WAIT); 188 } 189 if (error) 190 return (error); 191 fs->e2fs_ronly = 1; 192 } 193 if (mp->mnt_flag & MNT_RELOAD) { 194 error = ext2fs_reload(mp, ndp->ni_cnd.cn_cred, p); 195 if (error) 196 return (error); 197 } 198 if (fs->e2fs_ronly && (mp->mnt_flag & MNT_WANTRDWR)) { 199 fs->e2fs_ronly = 0; 200 if (fs->e2fs.e2fs_state == E2FS_ISCLEAN) 201 fs->e2fs.e2fs_state = 0; 202 else 203 fs->e2fs.e2fs_state = E2FS_ERRORS; 204 fs->e2fs_fmod = 1; 205 } 206 if (args && args->fspec == NULL) { 207 /* 208 * Process export requests. 209 */ 210 return (vfs_export(mp, &ump->um_export, 211 &args->export_info)); 212 } 213 if (args == NULL) 214 goto success; 215 } 216 /* 217 * Not an update, or updating the name: look up the name 218 * and verify that it refers to a sensible block device. 219 */ 220 error = copyinstr(args->fspec, fspec, sizeof(fspec), NULL); 221 if (error) 222 goto error; 223 224 if (disk_map(fspec, fname, MNAMELEN, DM_OPENBLCK) == -1) 225 memcpy(fname, fspec, sizeof(fname)); 226 227 NDINIT(ndp, LOOKUP, FOLLOW, UIO_SYSSPACE, fname, p); 228 if ((error = namei(ndp)) != 0) 229 goto error; 230 devvp = ndp->ni_vp; 231 232 if (devvp->v_type != VBLK) { 233 error = ENOTBLK; 234 goto error_devvp; 235 } 236 if (major(devvp->v_rdev) >= nblkdev) { 237 error = ENXIO; 238 goto error_devvp; 239 } 240 if ((mp->mnt_flag & MNT_UPDATE) == 0) 241 error = ext2fs_mountfs(devvp, mp, p); 242 else { 243 if (devvp != ump->um_devvp) 244 error = EINVAL; /* XXX needs translation */ 245 else 246 vrele(devvp); 247 } 248 if (error) 249 goto error_devvp; 250 ump = VFSTOUFS(mp); 251 fs = ump->um_e2fs; 252 253 memset(fs->e2fs_fsmnt, 0, sizeof(fs->e2fs_fsmnt)); 254 strlcpy(fs->e2fs_fsmnt, path, sizeof(fs->e2fs_fsmnt)); 255 if (fs->e2fs.e2fs_rev > E2FS_REV0) { 256 memset(fs->e2fs.e2fs_fsmnt, 0, sizeof(fs->e2fs.e2fs_fsmnt)); 257 strlcpy(fs->e2fs.e2fs_fsmnt, mp->mnt_stat.f_mntonname, 258 sizeof(fs->e2fs.e2fs_fsmnt)); 259 } 260 memcpy(mp->mnt_stat.f_mntonname, fs->e2fs_fsmnt, MNAMELEN); 261 memset(mp->mnt_stat.f_mntfromname, 0, MNAMELEN); 262 strlcpy(mp->mnt_stat.f_mntfromname, fname, MNAMELEN); 263 memset(mp->mnt_stat.f_mntfromspec, 0, MNAMELEN); 264 strlcpy(mp->mnt_stat.f_mntfromspec, fspec, MNAMELEN); 265 memcpy(&mp->mnt_stat.mount_info.ufs_args, args, sizeof(*args)); 266 267 if (fs->e2fs_fmod != 0) { /* XXX */ 268 fs->e2fs_fmod = 0; 269 if (fs->e2fs.e2fs_state == 0) 270 fs->e2fs.e2fs_wtime = gettime(); 271 else 272 printf("%s: file system not clean; please fsck(8)\n", 273 mp->mnt_stat.f_mntfromname); 274 ext2fs_cgupdate(ump, MNT_WAIT); 275 } 276 277 goto success; 278 279 error_devvp: 280 /* Error with devvp held. */ 281 vrele(devvp); 282 283 error: 284 /* Error with no state to backout. */ 285 286 success: 287 return (error); 288 } 289 290 int ext2fs_reload_vnode(struct vnode *, void *args); 291 292 struct ext2fs_reload_args { 293 struct m_ext2fs *fs; 294 struct proc *p; 295 struct ucred *cred; 296 struct vnode *devvp; 297 }; 298 299 int 300 ext2fs_reload_vnode(struct vnode *vp, void *args) 301 { 302 struct ext2fs_reload_args *era = args; 303 struct buf *bp; 304 struct inode *ip; 305 int error; 306 caddr_t cp; 307 308 /* 309 * Step 4: invalidate all inactive vnodes. 310 */ 311 if (vp->v_usecount == 0) { 312 vgonel(vp, era->p); 313 return (0); 314 } 315 316 /* 317 * Step 5: invalidate all cached file data. 318 */ 319 if (vget(vp, LK_EXCLUSIVE)) 320 return (0); 321 322 if (vinvalbuf(vp, 0, era->cred, era->p, 0, INFSLP)) 323 panic("ext2fs_reload: dirty2"); 324 /* 325 * Step 6: re-read inode data for all active vnodes. 326 */ 327 ip = VTOI(vp); 328 error = bread(era->devvp, 329 fsbtodb(era->fs, ino_to_fsba(era->fs, ip->i_number)), 330 (int)era->fs->e2fs_bsize, &bp); 331 if (error) { 332 vput(vp); 333 return (error); 334 } 335 cp = (caddr_t)bp->b_data + 336 (ino_to_fsbo(era->fs, ip->i_number) * EXT2_DINODE_SIZE(era->fs)); 337 e2fs_iload(era->fs, (struct ext2fs_dinode *)cp, ip->i_e2din); 338 brelse(bp); 339 vput(vp); 340 return (0); 341 } 342 343 static off_t 344 ext2fs_maxfilesize(struct m_ext2fs *fs) 345 { 346 bool huge = fs->e2fs.e2fs_features_rocompat & EXT2F_ROCOMPAT_HUGE_FILE; 347 off_t b = fs->e2fs_bsize / 4; 348 off_t physically, logically; 349 350 physically = dbtob(huge ? ((1ULL << 48) - 1) : UINT_MAX); 351 logically = (12ULL + b + b*b + b*b*b) * fs->e2fs_bsize; 352 353 return MIN(logically, physically); 354 } 355 356 static int 357 e2fs_sbfill(struct vnode *devvp, struct m_ext2fs *fs) 358 { 359 struct buf *bp = NULL; 360 int i, error; 361 362 /* XXX assume hardware block size == 512 */ 363 fs->e2fs_ncg = howmany(fs->e2fs.e2fs_bcount - fs->e2fs.e2fs_first_dblock, 364 fs->e2fs.e2fs_bpg); 365 fs->e2fs_fsbtodb = fs->e2fs.e2fs_log_bsize + 1; 366 fs->e2fs_bsize = 1024 << fs->e2fs.e2fs_log_bsize; 367 fs->e2fs_bshift = LOG_MINBSIZE + fs->e2fs.e2fs_log_bsize; 368 fs->e2fs_fsize = 1024 << fs->e2fs.e2fs_log_fsize; 369 370 fs->e2fs_qbmask = fs->e2fs_bsize - 1; 371 fs->e2fs_bmask = ~fs->e2fs_qbmask; 372 373 fs->e2fs_ipb = fs->e2fs_bsize / EXT2_DINODE_SIZE(fs); 374 fs->e2fs_itpg = fs->e2fs.e2fs_ipg / fs->e2fs_ipb; 375 376 /* Re-read group descriptors from the disk. */ 377 fs->e2fs_ngdb = howmany(fs->e2fs_ncg, 378 fs->e2fs_bsize / sizeof(struct ext2_gd)); 379 fs->e2fs_gd = mallocarray(fs->e2fs_ngdb, fs->e2fs_bsize, 380 M_UFSMNT, M_WAITOK); 381 382 for (i = 0; i < fs->e2fs_ngdb; ++i) { 383 daddr_t dblk = ((fs->e2fs_bsize > 1024) ? 0 : 1) + i + 1; 384 size_t gdesc = i * fs->e2fs_bsize / sizeof(struct ext2_gd); 385 struct ext2_gd *gd; 386 387 error = bread(devvp, fsbtodb(fs, dblk), fs->e2fs_bsize, &bp); 388 if (error) { 389 size_t gdescs_space = fs->e2fs_ngdb * fs->e2fs_bsize; 390 391 free(fs->e2fs_gd, M_UFSMNT, gdescs_space); 392 fs->e2fs_gd = NULL; 393 brelse(bp); 394 return (error); 395 } 396 397 gd = (struct ext2_gd *) bp->b_data; 398 e2fs_cgload(gd, fs->e2fs_gd + gdesc, fs->e2fs_bsize); 399 brelse(bp); 400 bp = NULL; 401 } 402 403 if (!(fs->e2fs.e2fs_features_rocompat & EXT2F_ROCOMPAT_LARGE_FILE) || 404 (fs->e2fs.e2fs_rev == E2FS_REV0)) 405 fs->e2fs_maxfilesize = INT_MAX; 406 else 407 fs->e2fs_maxfilesize = ext2fs_maxfilesize(fs); 408 409 if (fs->e2fs.e2fs_features_incompat & EXT2F_INCOMPAT_EXTENTS) 410 fs->e2fs_maxfilesize *= 4; 411 412 return (0); 413 } 414 415 /* 416 * Reload all incore data for a filesystem (used after running fsck on 417 * the root filesystem and finding things to fix). The filesystem must 418 * be mounted read-only. 419 * 420 * Things to do to update the mount: 421 * 1) invalidate all cached meta-data. 422 * 2) re-read superblock from disk. 423 * 3) re-read summary information from disk. 424 * 4) invalidate all inactive vnodes. 425 * 5) invalidate all cached file data. 426 * 6) re-read inode data for all active vnodes. 427 */ 428 int 429 ext2fs_reload(struct mount *mountp, struct ucred *cred, struct proc *p) 430 { 431 struct vnode *devvp; 432 struct buf *bp; 433 struct m_ext2fs *fs; 434 struct ext2fs *newfs; 435 int error; 436 struct ext2fs_reload_args era; 437 438 if ((mountp->mnt_flag & MNT_RDONLY) == 0) 439 return (EINVAL); 440 /* 441 * Step 1: invalidate all cached meta-data. 442 */ 443 devvp = VFSTOUFS(mountp)->um_devvp; 444 vn_lock(devvp, LK_EXCLUSIVE | LK_RETRY); 445 error = vinvalbuf(devvp, 0, cred, p, 0, INFSLP); 446 VOP_UNLOCK(devvp); 447 if (error != 0) 448 panic("ext2fs_reload: dirty1"); 449 450 /* 451 * Step 2: re-read superblock from disk. 452 */ 453 error = bread(devvp, (daddr_t)(SBOFF / DEV_BSIZE), SBSIZE, &bp); 454 if (error) { 455 brelse(bp); 456 return (error); 457 } 458 newfs = (struct ext2fs *)bp->b_data; 459 error = e2fs_sbcheck(newfs, (mountp->mnt_flag & MNT_RDONLY)); 460 if (error) { 461 brelse(bp); 462 return (error); 463 } 464 465 fs = VFSTOUFS(mountp)->um_e2fs; 466 /* 467 * Copy in the new superblock, compute in-memory values 468 * and load group descriptors. 469 */ 470 e2fs_sbload(newfs, &fs->e2fs); 471 if ((error = e2fs_sbfill(devvp, fs)) != 0) 472 return (error); 473 474 era.p = p; 475 era.cred = cred; 476 era.fs = fs; 477 era.devvp = devvp; 478 479 error = vfs_mount_foreach_vnode(mountp, ext2fs_reload_vnode, &era); 480 481 return (error); 482 } 483 484 /* 485 * Common code for mount and mountroot 486 */ 487 int 488 ext2fs_mountfs(struct vnode *devvp, struct mount *mp, struct proc *p) 489 { 490 struct ufsmount *ump; 491 struct buf *bp; 492 struct ext2fs *fs; 493 dev_t dev; 494 int error, ronly; 495 struct ucred *cred; 496 497 dev = devvp->v_rdev; 498 cred = p ? p->p_ucred : NOCRED; 499 /* 500 * Disallow multiple mounts of the same device. 501 * Disallow mounting of a device that is currently in use 502 * (except for root, which might share swap device for miniroot). 503 * Flush out any old buffers remaining from a previous use. 504 */ 505 if ((error = vfs_mountedon(devvp)) != 0) 506 return (error); 507 if (vcount(devvp) > 1 && devvp != rootvp) 508 return (EBUSY); 509 vn_lock(devvp, LK_EXCLUSIVE | LK_RETRY); 510 error = vinvalbuf(devvp, V_SAVE, cred, p, 0, INFSLP); 511 VOP_UNLOCK(devvp); 512 if (error != 0) 513 return (error); 514 515 ronly = (mp->mnt_flag & MNT_RDONLY) != 0; 516 error = VOP_OPEN(devvp, ronly ? FREAD : FREAD|FWRITE, FSCRED, p); 517 if (error) 518 return (error); 519 520 bp = NULL; 521 ump = NULL; 522 523 /* 524 * Read the superblock from disk. 525 */ 526 error = bread(devvp, (daddr_t)(SBOFF / DEV_BSIZE), SBSIZE, &bp); 527 if (error) 528 goto out; 529 fs = (struct ext2fs *)bp->b_data; 530 error = e2fs_sbcheck(fs, ronly); 531 if (error) 532 goto out; 533 534 ump = malloc(sizeof *ump, M_UFSMNT, M_WAITOK | M_ZERO); 535 ump->um_e2fs = malloc(sizeof(struct m_ext2fs), M_UFSMNT, 536 M_WAITOK | M_ZERO); 537 538 /* 539 * Copy in the superblock, compute in-memory values 540 * and load group descriptors. 541 */ 542 e2fs_sbload(fs, &ump->um_e2fs->e2fs); 543 if ((error = e2fs_sbfill(devvp, ump->um_e2fs)) != 0) 544 goto out; 545 brelse(bp); 546 bp = NULL; 547 fs = &ump->um_e2fs->e2fs; 548 ump->um_e2fs->e2fs_ronly = ronly; 549 ump->um_fstype = UM_EXT2FS; 550 551 if (ronly == 0) { 552 if (fs->e2fs_state == E2FS_ISCLEAN) 553 fs->e2fs_state = 0; 554 else 555 fs->e2fs_state = E2FS_ERRORS; 556 ump->um_e2fs->e2fs_fmod = 1; 557 } 558 559 mp->mnt_data = ump; 560 mp->mnt_stat.f_fsid.val[0] = (long)dev; 561 mp->mnt_stat.f_fsid.val[1] = mp->mnt_vfc->vfc_typenum; 562 mp->mnt_stat.f_namemax = MAXNAMLEN; 563 mp->mnt_flag |= MNT_LOCAL; 564 ump->um_mountp = mp; 565 ump->um_dev = dev; 566 ump->um_devvp = devvp; 567 ump->um_nindir = NINDIR(ump->um_e2fs); 568 ump->um_bptrtodb = ump->um_e2fs->e2fs_fsbtodb; 569 ump->um_seqinc = 1; /* no frags */ 570 ump->um_maxsymlinklen = EXT2_MAXSYMLINKLEN; 571 devvp->v_specmountpoint = mp; 572 return (0); 573 out: 574 if (devvp->v_specinfo) 575 devvp->v_specmountpoint = NULL; 576 if (bp) 577 brelse(bp); 578 vn_lock(devvp, LK_EXCLUSIVE | LK_RETRY); 579 (void)VOP_CLOSE(devvp, ronly ? FREAD : FREAD|FWRITE, cred, p); 580 VOP_UNLOCK(devvp); 581 if (ump) { 582 free(ump->um_e2fs, M_UFSMNT, sizeof *ump->um_e2fs); 583 free(ump, M_UFSMNT, sizeof *ump); 584 mp->mnt_data = NULL; 585 } 586 return (error); 587 } 588 589 /* 590 * unmount system call 591 */ 592 int 593 ext2fs_unmount(struct mount *mp, int mntflags, struct proc *p) 594 { 595 struct ufsmount *ump; 596 struct m_ext2fs *fs; 597 int error, flags; 598 size_t gdescs_space; 599 600 flags = 0; 601 if (mntflags & MNT_FORCE) 602 flags |= FORCECLOSE; 603 if ((error = ext2fs_flushfiles(mp, flags, p)) != 0) 604 return (error); 605 ump = VFSTOUFS(mp); 606 fs = ump->um_e2fs; 607 gdescs_space = fs->e2fs_ngdb * fs->e2fs_bsize; 608 609 if (!fs->e2fs_ronly && ext2fs_cgupdate(ump, MNT_WAIT) == 0 && 610 (fs->e2fs.e2fs_state & E2FS_ERRORS) == 0) { 611 fs->e2fs.e2fs_state = E2FS_ISCLEAN; 612 (void) ext2fs_sbupdate(ump, MNT_WAIT); 613 } 614 615 if (ump->um_devvp->v_type != VBAD) 616 ump->um_devvp->v_specmountpoint = NULL; 617 vn_lock(ump->um_devvp, LK_EXCLUSIVE | LK_RETRY); 618 (void)VOP_CLOSE(ump->um_devvp, fs->e2fs_ronly ? FREAD : FREAD|FWRITE, 619 NOCRED, p); 620 vput(ump->um_devvp); 621 free(fs->e2fs_gd, M_UFSMNT, gdescs_space); 622 free(fs, M_UFSMNT, sizeof *fs); 623 free(ump, M_UFSMNT, sizeof *ump); 624 mp->mnt_data = NULL; 625 mp->mnt_flag &= ~MNT_LOCAL; 626 return (0); 627 } 628 629 /* 630 * Flush out all the files in a filesystem. 631 */ 632 int 633 ext2fs_flushfiles(struct mount *mp, int flags, struct proc *p) 634 { 635 struct ufsmount *ump; 636 int error; 637 638 ump = VFSTOUFS(mp); 639 /* 640 * Flush all the files. 641 */ 642 if ((error = vflush(mp, NULL, flags)) != 0) 643 return (error); 644 /* 645 * Flush filesystem metadata. 646 */ 647 vn_lock(ump->um_devvp, LK_EXCLUSIVE | LK_RETRY); 648 error = VOP_FSYNC(ump->um_devvp, p->p_ucred, MNT_WAIT, p); 649 VOP_UNLOCK(ump->um_devvp); 650 return (error); 651 } 652 653 /* 654 * Get file system statistics. 655 */ 656 int 657 ext2fs_statfs(struct mount *mp, struct statfs *sbp, struct proc *p) 658 { 659 struct ufsmount *ump; 660 struct m_ext2fs *fs; 661 u_int32_t overhead, overhead_per_group; 662 int i, ngroups; 663 664 ump = VFSTOUFS(mp); 665 fs = ump->um_e2fs; 666 if (fs->e2fs.e2fs_magic != E2FS_MAGIC) 667 panic("ext2fs_statfs"); 668 669 /* 670 * Compute the overhead (FS structures) 671 */ 672 overhead_per_group = 1 /* block bitmap */ + 1 /* inode bitmap */ + 673 fs->e2fs_itpg; 674 overhead = fs->e2fs.e2fs_first_dblock + 675 fs->e2fs_ncg * overhead_per_group; 676 if (fs->e2fs.e2fs_rev > E2FS_REV0 && 677 fs->e2fs.e2fs_features_rocompat & EXT2F_ROCOMPAT_SPARSE_SUPER) { 678 for (i = 0, ngroups = 0; i < fs->e2fs_ncg; i++) { 679 if (cg_has_sb(i)) 680 ngroups++; 681 } 682 } else { 683 ngroups = fs->e2fs_ncg; 684 } 685 overhead += ngroups * (1 + fs->e2fs_ngdb); 686 687 sbp->f_bsize = fs->e2fs_bsize; 688 sbp->f_iosize = fs->e2fs_bsize; 689 sbp->f_blocks = fs->e2fs.e2fs_bcount - overhead; 690 sbp->f_bfree = fs->e2fs.e2fs_fbcount; 691 sbp->f_bavail = sbp->f_bfree - fs->e2fs.e2fs_rbcount; 692 sbp->f_files = fs->e2fs.e2fs_icount; 693 sbp->f_favail = sbp->f_ffree = fs->e2fs.e2fs_ficount; 694 copy_statfs_info(sbp, mp); 695 696 return (0); 697 } 698 699 int ext2fs_sync_vnode(struct vnode *vp, void *); 700 701 struct ext2fs_sync_args { 702 int allerror; 703 int waitfor; 704 int nlink0; 705 int inflight; 706 struct proc *p; 707 struct ucred *cred; 708 }; 709 710 int 711 ext2fs_sync_vnode(struct vnode *vp, void *args) 712 { 713 struct ext2fs_sync_args *esa = args; 714 struct inode *ip; 715 int error, nlink0 = 0; 716 int s, skip = 0; 717 718 if (vp->v_type == VNON) 719 return (0); 720 721 ip = VTOI(vp); 722 723 if (ip->i_e2fs_nlink == 0) 724 nlink0 = 1; 725 726 s = splbio(); 727 if ((ip->i_flag & (IN_ACCESS | IN_CHANGE | IN_MODIFIED | IN_UPDATE)) == 0 && 728 LIST_EMPTY(&vp->v_dirtyblkhd)) { 729 skip = 1; 730 } 731 splx(s); 732 733 if (skip) 734 goto end; 735 736 if (vget(vp, LK_EXCLUSIVE | LK_NOWAIT)) { 737 esa->inflight = MIN(esa->inflight+1, 65536); 738 goto end; 739 } 740 741 if ((error = VOP_FSYNC(vp, esa->cred, esa->waitfor, esa->p)) != 0) 742 esa->allerror = error; 743 vput(vp); 744 end: 745 esa->nlink0 = MIN(esa->nlink0 + nlink0, 65536); 746 return (0); 747 } 748 749 /* 750 * Go through the disk queues to initiate sandbagged IO; 751 * go through the inodes to write those that have been modified; 752 * initiate the writing of the super block if it has been modified. 753 * 754 * Should always be called with the mount point locked. 755 */ 756 int 757 ext2fs_sync(struct mount *mp, int waitfor, int stall, 758 struct ucred *cred, struct proc *p) 759 { 760 struct ufsmount *ump = VFSTOUFS(mp); 761 struct m_ext2fs *fs; 762 int error, allerror = 0, state, fmod; 763 struct ext2fs_sync_args esa; 764 765 fs = ump->um_e2fs; 766 if (fs->e2fs_ronly != 0) { /* XXX */ 767 printf("fs = %s\n", fs->e2fs_fsmnt); 768 panic("update: rofs mod"); 769 } 770 771 /* 772 * Write back each (modified) inode. 773 */ 774 esa.p = p; 775 esa.cred = cred; 776 esa.allerror = 0; 777 esa.waitfor = waitfor; 778 esa.nlink0 = 0; 779 esa.inflight = 0; 780 781 vfs_mount_foreach_vnode(mp, ext2fs_sync_vnode, &esa); 782 if (esa.allerror != 0) 783 allerror = esa.allerror; 784 785 /* 786 * Force stale file system control information to be flushed. 787 */ 788 if (waitfor != MNT_LAZY) { 789 vn_lock(ump->um_devvp, LK_EXCLUSIVE | LK_RETRY); 790 if ((error = VOP_FSYNC(ump->um_devvp, cred, waitfor, p)) != 0) 791 allerror = error; 792 VOP_UNLOCK(ump->um_devvp); 793 } 794 /* 795 * Write back modified superblock. 796 */ 797 state = fs->e2fs.e2fs_state; 798 fmod = fs->e2fs_fmod; 799 if (stall && fs->e2fs_ronly == 0) { 800 fs->e2fs_fmod = 1; 801 if (allerror == 0 && esa.nlink0 == 0 && esa.inflight == 0) { 802 if ((fs->e2fs.e2fs_state & E2FS_ERRORS) == 0) 803 fs->e2fs.e2fs_state = E2FS_ISCLEAN; 804 #if 0 805 printf("%s force clean (dangling %d inflight %d)\n", 806 mp->mnt_stat.f_mntonname, esa.nlink0, esa.inflight); 807 #endif 808 } else { 809 fs->e2fs.e2fs_state = 0; 810 #if 0 811 printf("%s force dirty (dangling %d inflight %d)\n", 812 mp->mnt_stat.f_mntonname, esa.nlink0, esa.inflight); 813 #endif 814 } 815 } 816 if (fs->e2fs_fmod != 0) { 817 fs->e2fs_fmod = 0; 818 fs->e2fs.e2fs_wtime = gettime(); 819 if ((error = ext2fs_cgupdate(ump, waitfor))) 820 allerror = error; 821 } 822 fs->e2fs.e2fs_state = state; 823 fs->e2fs_fmod = fmod; 824 return (allerror); 825 } 826 827 /* 828 * Look up a EXT2FS dinode number to find its incore vnode, otherwise read it 829 * in from disk. If it is in core, wait for the lock bit to clear, then 830 * return the inode locked. Detection and handling of mount points must be 831 * done by the calling routine. 832 */ 833 int 834 ext2fs_vget(struct mount *mp, ino_t ino, struct vnode **vpp) 835 { 836 struct m_ext2fs *fs; 837 struct inode *ip; 838 struct ext2fs_dinode *dp; 839 struct ufsmount *ump; 840 struct buf *bp; 841 struct vnode *vp; 842 dev_t dev; 843 int error; 844 845 if (ino > (ufsino_t)-1) 846 panic("ext2fs_vget: alien ino_t %llu", 847 (unsigned long long)ino); 848 849 ump = VFSTOUFS(mp); 850 dev = ump->um_dev; 851 852 retry: 853 if ((*vpp = ufs_ihashget(dev, ino)) != NULL) 854 return (0); 855 856 /* Allocate a new vnode/inode. */ 857 if ((error = getnewvnode(VT_EXT2FS, mp, &ext2fs_vops, &vp)) != 0) { 858 *vpp = NULL; 859 return (error); 860 } 861 862 ip = pool_get(&ext2fs_inode_pool, PR_WAITOK|PR_ZERO); 863 rrw_init_flags(&ip->i_lock, "inode", RWL_DUPOK | RWL_IS_VNODE); 864 vp->v_data = ip; 865 ip->i_vnode = vp; 866 ip->i_ump = ump; 867 ip->i_e2fs = fs = ump->um_e2fs; 868 ip->i_dev = dev; 869 ip->i_number = ino; 870 ip->i_e2fs_last_lblk = 0; 871 ip->i_e2fs_last_blk = 0; 872 873 /* 874 * Put it onto its hash chain and lock it so that other requests for 875 * this inode will block if they arrive while we are sleeping waiting 876 * for old data structures to be purged or for the contents of the 877 * disk portion of this inode to be read. 878 */ 879 error = ufs_ihashins(ip); 880 881 if (error) { 882 vrele(vp); 883 884 if (error == EEXIST) 885 goto retry; 886 887 return (error); 888 } 889 890 /* Read in the disk contents for the inode, copy into the inode. */ 891 error = bread(ump->um_devvp, fsbtodb(fs, ino_to_fsba(fs, ino)), 892 (int)fs->e2fs_bsize, &bp); 893 if (error) { 894 /* 895 * The inode does not contain anything useful, so it would 896 * be misleading to leave it on its hash chain. With mode 897 * still zero, it will be unlinked and returned to the free 898 * list by vput(). 899 */ 900 vput(vp); 901 brelse(bp); 902 *vpp = NULL; 903 return (error); 904 } 905 906 dp = (struct ext2fs_dinode *) ((char *)bp->b_data 907 + EXT2_DINODE_SIZE(fs) * ino_to_fsbo(fs, ino)); 908 909 ip->i_e2din = pool_get(&ext2fs_dinode_pool, PR_WAITOK); 910 e2fs_iload(fs, dp, ip->i_e2din); 911 brelse(bp); 912 913 ip->i_effnlink = ip->i_e2fs_nlink; 914 915 /* 916 * The fields for storing the UID and GID of an ext2fs inode are 917 * limited to 16 bits. To overcome this limitation, Linux decided to 918 * scatter the highest bits of these values into a previously reserved 919 * area on the disk inode. We deal with this situation by having two 920 * 32-bit fields *out* of the disk inode to hold the complete values. 921 * Now that we are reading in the inode, compute these fields. 922 */ 923 ip->i_e2fs_uid = ip->i_e2fs_uid_low | (ip->i_e2fs_uid_high << 16); 924 ip->i_e2fs_gid = ip->i_e2fs_gid_low | (ip->i_e2fs_gid_high << 16); 925 926 /* If the inode was deleted, reset all fields */ 927 if (ip->i_e2fs_dtime != 0) { 928 ip->i_e2fs_mode = ip->i_e2fs_nblock = 0; 929 (void)ext2fs_setsize(ip, 0); 930 } 931 932 /* 933 * Initialize the vnode from the inode, check for aliases. 934 * Note that the underlying vnode may have changed. 935 */ 936 error = ext2fs_vinit(mp, &vp); 937 if (error) { 938 vput(vp); 939 *vpp = NULL; 940 return (error); 941 } 942 943 /* 944 * Finish inode initialization now that aliasing has been resolved. 945 */ 946 vref(ip->i_devvp); 947 /* 948 * Set up a generation number for this inode if it does not 949 * already have one. This should only happen on old filesystems. 950 */ 951 if (ip->i_e2fs_gen == 0) { 952 if (++ext2gennumber < (u_long)gettime()) 953 ext2gennumber = gettime(); 954 ip->i_e2fs_gen = ext2gennumber; 955 if ((vp->v_mount->mnt_flag & MNT_RDONLY) == 0) 956 ip->i_flag |= IN_MODIFIED; 957 } 958 959 *vpp = vp; 960 return (0); 961 } 962 963 /* 964 * File handle to vnode 965 * 966 * Have to be really careful about stale file handles: 967 * - check that the inode number is valid 968 * - call ext2fs_vget() to get the locked inode 969 * - check for an unallocated inode (i_mode == 0) 970 * - check that the given client host has export rights and return 971 * those rights via. exflagsp and credanonp 972 */ 973 int 974 ext2fs_fhtovp(struct mount *mp, struct fid *fhp, struct vnode **vpp) 975 { 976 struct inode *ip; 977 struct vnode *nvp; 978 int error; 979 struct ufid *ufhp; 980 struct m_ext2fs *fs; 981 982 ufhp = (struct ufid *)fhp; 983 fs = VFSTOUFS(mp)->um_e2fs; 984 if ((ufhp->ufid_ino < EXT2_FIRSTINO && ufhp->ufid_ino != EXT2_ROOTINO) || 985 ufhp->ufid_ino > fs->e2fs_ncg * fs->e2fs.e2fs_ipg) 986 return (ESTALE); 987 988 if ((error = VFS_VGET(mp, ufhp->ufid_ino, &nvp)) != 0) { 989 *vpp = NULLVP; 990 return (error); 991 } 992 ip = VTOI(nvp); 993 if (ip->i_e2fs_mode == 0 || ip->i_e2fs_dtime != 0 || 994 ip->i_e2fs_gen != ufhp->ufid_gen) { 995 vput(nvp); 996 *vpp = NULLVP; 997 return (ESTALE); 998 } 999 *vpp = nvp; 1000 return (0); 1001 } 1002 1003 /* 1004 * Vnode pointer to File handle 1005 */ 1006 int 1007 ext2fs_vptofh(struct vnode *vp, struct fid *fhp) 1008 { 1009 struct inode *ip; 1010 struct ufid *ufhp; 1011 1012 ip = VTOI(vp); 1013 ufhp = (struct ufid *)fhp; 1014 ufhp->ufid_len = sizeof(struct ufid); 1015 ufhp->ufid_ino = ip->i_number; 1016 ufhp->ufid_gen = ip->i_e2fs_gen; 1017 return (0); 1018 } 1019 1020 /* 1021 * no sysctl for ext2fs 1022 */ 1023 1024 int 1025 ext2fs_sysctl(int *name, u_int namelen, void *oldp, size_t *oldlenp, 1026 void *newp, size_t newlen, struct proc *p) 1027 { 1028 return (EOPNOTSUPP); 1029 } 1030 1031 /* 1032 * Write a superblock and associated information back to disk. 1033 */ 1034 int 1035 ext2fs_sbupdate(struct ufsmount *mp, int waitfor) 1036 { 1037 struct m_ext2fs *fs = mp->um_e2fs; 1038 struct buf *bp; 1039 int error = 0; 1040 1041 bp = getblk(mp->um_devvp, SBLOCK, SBSIZE, 0, INFSLP); 1042 e2fs_sbsave(&fs->e2fs, (struct ext2fs *) bp->b_data); 1043 if (waitfor == MNT_WAIT) 1044 error = bwrite(bp); 1045 else 1046 bawrite(bp); 1047 fs->e2fs_fmod = 0; 1048 return (error); 1049 } 1050 1051 int 1052 ext2fs_cgupdate(struct ufsmount *mp, int waitfor) 1053 { 1054 struct m_ext2fs *fs = mp->um_e2fs; 1055 struct buf *bp; 1056 int i, error = 0, allerror = 0; 1057 1058 allerror = ext2fs_sbupdate(mp, waitfor); 1059 for (i = 0; i < fs->e2fs_ngdb; i++) { 1060 bp = getblk(mp->um_devvp, fsbtodb(fs, ((fs->e2fs_bsize>1024)?0:1)+i+1), 1061 fs->e2fs_bsize, 0, INFSLP); 1062 e2fs_cgsave(&fs->e2fs_gd[i* fs->e2fs_bsize / sizeof(struct ext2_gd)], (struct ext2_gd*)bp->b_data, fs->e2fs_bsize); 1063 if (waitfor == MNT_WAIT) 1064 error = bwrite(bp); 1065 else 1066 bawrite(bp); 1067 } 1068 1069 if (!allerror && error) 1070 allerror = error; 1071 return (allerror); 1072 } 1073 1074 /* This is called before the superblock is copied. Watch out for endianity! */ 1075 static int 1076 e2fs_sbcheck(struct ext2fs *fs, int ronly) 1077 { 1078 u_int32_t mask, tmp; 1079 int i; 1080 1081 tmp = letoh16(fs->e2fs_magic); 1082 if (tmp != E2FS_MAGIC) { 1083 printf("ext2fs: wrong magic number 0x%x\n", tmp); 1084 return (EIO); /* XXX needs translation */ 1085 } 1086 1087 tmp = letoh32(fs->e2fs_log_bsize); 1088 if (tmp > 2) { 1089 /* skewed log(block size): 1024 -> 0 | 2048 -> 1 | 4096 -> 2 */ 1090 tmp += 10; 1091 printf("ext2fs: wrong log2(block size) %d\n", tmp); 1092 return (EIO); /* XXX needs translation */ 1093 } 1094 1095 if (fs->e2fs_bpg == 0) { 1096 printf("ext2fs: zero blocks per group\n"); 1097 return (EIO); 1098 } 1099 1100 tmp = letoh32(fs->e2fs_rev); 1101 if (tmp > E2FS_REV1) { 1102 printf("ext2fs: wrong revision number 0x%x\n", tmp); 1103 return (EIO); /* XXX needs translation */ 1104 } 1105 else if (tmp == E2FS_REV0) 1106 return (0); 1107 1108 tmp = letoh32(fs->e2fs_first_ino); 1109 if (tmp != EXT2_FIRSTINO) { 1110 printf("ext2fs: first inode at 0x%x\n", tmp); 1111 return (EINVAL); /* XXX needs translation */ 1112 } 1113 1114 tmp = letoh32(fs->e2fs_features_incompat); 1115 mask = tmp & ~(EXT2F_INCOMPAT_SUPP | EXT4F_RO_INCOMPAT_SUPP); 1116 if (mask) { 1117 printf("ext2fs: unsupported incompat features: "); 1118 for (i = 0; i < nitems(incompat); i++) 1119 if (mask & incompat[i].mask) 1120 printf("%s ", incompat[i].name); 1121 printf("\n"); 1122 return (EINVAL); /* XXX needs translation */ 1123 } 1124 1125 if (!ronly && (tmp & EXT4F_RO_INCOMPAT_SUPP)) { 1126 printf("ext4fs: only read-only support right now\n"); 1127 return (EROFS); /* XXX needs translation */ 1128 } 1129 1130 if (tmp & EXT2F_INCOMPAT_RECOVER) { 1131 printf("ext2fs: your file system says it needs recovery\n"); 1132 if (!ronly) 1133 return (EROFS); /* XXX needs translation */ 1134 } 1135 1136 tmp = letoh32(fs->e2fs_features_rocompat) & ~EXT2F_ROCOMPAT_SUPP; 1137 if (!ronly && tmp) { 1138 printf("ext2fs: unsupported R/O compat features: "); 1139 for (i = 0; i < nitems(ro_compat); i++) 1140 if (tmp & ro_compat[i].mask) 1141 printf("%s ", ro_compat[i].name); 1142 printf("\n"); 1143 return (EROFS); /* XXX needs translation */ 1144 } 1145 1146 return (0); 1147 } 1148