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