1 /* $OpenBSD: ext2fs_vfsops.c,v 1.115 2020/06/24 22:03:44 cheloha 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 717 if (vp->v_type == VNON) 718 return (0); 719 720 if (vp->v_inflight) 721 esa->inflight = MIN(esa->inflight+1, 65536); 722 723 ip = VTOI(vp); 724 725 if (ip->i_e2fs_nlink == 0) 726 nlink0 = 1; 727 728 if ((ip->i_flag & (IN_ACCESS | IN_CHANGE | IN_MODIFIED | IN_UPDATE)) == 0 && 729 LIST_EMPTY(&vp->v_dirtyblkhd)) { 730 goto end; 731 } 732 733 if (vget(vp, LK_EXCLUSIVE | LK_NOWAIT)) { 734 nlink0 = 1; /* potentially */ 735 goto end; 736 } 737 738 if ((error = VOP_FSYNC(vp, esa->cred, esa->waitfor, esa->p)) != 0) 739 esa->allerror = error; 740 vput(vp); 741 end: 742 esa->nlink0 = MIN(esa->nlink0 + nlink0, 65536); 743 return (0); 744 } 745 /* 746 * Go through the disk queues to initiate sandbagged IO; 747 * go through the inodes to write those that have been modified; 748 * initiate the writing of the super block if it has been modified. 749 * 750 * Should always be called with the mount point locked. 751 */ 752 int 753 ext2fs_sync(struct mount *mp, int waitfor, int stall, 754 struct ucred *cred, struct proc *p) 755 { 756 struct ufsmount *ump = VFSTOUFS(mp); 757 struct m_ext2fs *fs; 758 int error, allerror = 0, state, fmod; 759 struct ext2fs_sync_args esa; 760 761 fs = ump->um_e2fs; 762 if (fs->e2fs_ronly != 0) { /* XXX */ 763 printf("fs = %s\n", fs->e2fs_fsmnt); 764 panic("update: rofs mod"); 765 } 766 767 /* 768 * Write back each (modified) inode. 769 */ 770 esa.p = p; 771 esa.cred = cred; 772 esa.allerror = 0; 773 esa.waitfor = waitfor; 774 esa.nlink0 = 0; 775 esa.inflight = 0; 776 777 vfs_mount_foreach_vnode(mp, ext2fs_sync_vnode, &esa); 778 if (esa.allerror != 0) 779 allerror = esa.allerror; 780 781 /* 782 * Force stale file system control information to be flushed. 783 */ 784 if (waitfor != MNT_LAZY) { 785 vn_lock(ump->um_devvp, LK_EXCLUSIVE | LK_RETRY); 786 if ((error = VOP_FSYNC(ump->um_devvp, cred, waitfor, p)) != 0) 787 allerror = error; 788 VOP_UNLOCK(ump->um_devvp); 789 } 790 /* 791 * Write back modified superblock. 792 */ 793 state = fs->e2fs.e2fs_state; 794 fmod = fs->e2fs_fmod; 795 if (stall && fs->e2fs_ronly == 0) { 796 fs->e2fs_fmod = 1; 797 if (allerror == 0 && esa.nlink0 == 0 && esa.inflight == 0) { 798 if ((fs->e2fs.e2fs_state & E2FS_ERRORS) == 0) 799 fs->e2fs.e2fs_state = E2FS_ISCLEAN; 800 #if 0 801 printf("%s force clean (dangling %d inflight %d)\n", 802 mp->mnt_stat.f_mntonname, esa.nlink0, esa.inflight); 803 #endif 804 } else { 805 fs->e2fs.e2fs_state = 0; 806 #if 0 807 printf("%s force dirty (dangling %d inflight %d)\n", 808 mp->mnt_stat.f_mntonname, esa.nlink0, esa.inflight); 809 #endif 810 } 811 } 812 if (fs->e2fs_fmod != 0) { 813 fs->e2fs_fmod = 0; 814 fs->e2fs.e2fs_wtime = gettime(); 815 if ((error = ext2fs_cgupdate(ump, waitfor))) 816 allerror = error; 817 } 818 fs->e2fs.e2fs_state = state; 819 fs->e2fs_fmod = fmod; 820 return (allerror); 821 } 822 823 /* 824 * Look up a EXT2FS dinode number to find its incore vnode, otherwise read it 825 * in from disk. If it is in core, wait for the lock bit to clear, then 826 * return the inode locked. Detection and handling of mount points must be 827 * done by the calling routine. 828 */ 829 int 830 ext2fs_vget(struct mount *mp, ino_t ino, struct vnode **vpp) 831 { 832 struct m_ext2fs *fs; 833 struct inode *ip; 834 struct ext2fs_dinode *dp; 835 struct ufsmount *ump; 836 struct buf *bp; 837 struct vnode *vp; 838 dev_t dev; 839 int error; 840 841 if (ino > (ufsino_t)-1) 842 panic("ext2fs_vget: alien ino_t %llu", 843 (unsigned long long)ino); 844 845 ump = VFSTOUFS(mp); 846 dev = ump->um_dev; 847 848 retry: 849 if ((*vpp = ufs_ihashget(dev, ino)) != NULL) 850 return (0); 851 852 /* Allocate a new vnode/inode. */ 853 if ((error = getnewvnode(VT_EXT2FS, mp, &ext2fs_vops, &vp)) != 0) { 854 *vpp = NULL; 855 return (error); 856 } 857 858 ip = pool_get(&ext2fs_inode_pool, PR_WAITOK|PR_ZERO); 859 rrw_init_flags(&ip->i_lock, "inode", RWL_DUPOK | RWL_IS_VNODE); 860 vp->v_data = ip; 861 ip->i_vnode = vp; 862 ip->i_ump = ump; 863 ip->i_e2fs = fs = ump->um_e2fs; 864 ip->i_dev = dev; 865 ip->i_number = ino; 866 ip->i_e2fs_last_lblk = 0; 867 ip->i_e2fs_last_blk = 0; 868 869 /* 870 * Put it onto its hash chain and lock it so that other requests for 871 * this inode will block if they arrive while we are sleeping waiting 872 * for old data structures to be purged or for the contents of the 873 * disk portion of this inode to be read. 874 */ 875 error = ufs_ihashins(ip); 876 877 if (error) { 878 vrele(vp); 879 880 if (error == EEXIST) 881 goto retry; 882 883 return (error); 884 } 885 886 /* Read in the disk contents for the inode, copy into the inode. */ 887 error = bread(ump->um_devvp, fsbtodb(fs, ino_to_fsba(fs, ino)), 888 (int)fs->e2fs_bsize, &bp); 889 if (error) { 890 /* 891 * The inode does not contain anything useful, so it would 892 * be misleading to leave it on its hash chain. With mode 893 * still zero, it will be unlinked and returned to the free 894 * list by vput(). 895 */ 896 vput(vp); 897 brelse(bp); 898 *vpp = NULL; 899 return (error); 900 } 901 902 dp = (struct ext2fs_dinode *) ((char *)bp->b_data 903 + EXT2_DINODE_SIZE(fs) * ino_to_fsbo(fs, ino)); 904 905 ip->i_e2din = pool_get(&ext2fs_dinode_pool, PR_WAITOK); 906 e2fs_iload(fs, dp, ip->i_e2din); 907 brelse(bp); 908 909 ip->i_effnlink = ip->i_e2fs_nlink; 910 911 /* 912 * The fields for storing the UID and GID of an ext2fs inode are 913 * limited to 16 bits. To overcome this limitation, Linux decided to 914 * scatter the highest bits of these values into a previously reserved 915 * area on the disk inode. We deal with this situation by having two 916 * 32-bit fields *out* of the disk inode to hold the complete values. 917 * Now that we are reading in the inode, compute these fields. 918 */ 919 ip->i_e2fs_uid = ip->i_e2fs_uid_low | (ip->i_e2fs_uid_high << 16); 920 ip->i_e2fs_gid = ip->i_e2fs_gid_low | (ip->i_e2fs_gid_high << 16); 921 922 /* If the inode was deleted, reset all fields */ 923 if (ip->i_e2fs_dtime != 0) { 924 ip->i_e2fs_mode = ip->i_e2fs_nblock = 0; 925 (void)ext2fs_setsize(ip, 0); 926 } 927 928 /* 929 * Initialize the vnode from the inode, check for aliases. 930 * Note that the underlying vnode may have changed. 931 */ 932 error = ext2fs_vinit(mp, &vp); 933 if (error) { 934 vput(vp); 935 *vpp = NULL; 936 return (error); 937 } 938 939 /* 940 * Finish inode initialization now that aliasing has been resolved. 941 */ 942 vref(ip->i_devvp); 943 /* 944 * Set up a generation number for this inode if it does not 945 * already have one. This should only happen on old filesystems. 946 */ 947 if (ip->i_e2fs_gen == 0) { 948 if (++ext2gennumber < (u_long)gettime()) 949 ext2gennumber = gettime(); 950 ip->i_e2fs_gen = ext2gennumber; 951 if ((vp->v_mount->mnt_flag & MNT_RDONLY) == 0) 952 ip->i_flag |= IN_MODIFIED; 953 } 954 955 *vpp = vp; 956 return (0); 957 } 958 959 /* 960 * File handle to vnode 961 * 962 * Have to be really careful about stale file handles: 963 * - check that the inode number is valid 964 * - call ext2fs_vget() to get the locked inode 965 * - check for an unallocated inode (i_mode == 0) 966 * - check that the given client host has export rights and return 967 * those rights via. exflagsp and credanonp 968 */ 969 int 970 ext2fs_fhtovp(struct mount *mp, struct fid *fhp, struct vnode **vpp) 971 { 972 struct inode *ip; 973 struct vnode *nvp; 974 int error; 975 struct ufid *ufhp; 976 struct m_ext2fs *fs; 977 978 ufhp = (struct ufid *)fhp; 979 fs = VFSTOUFS(mp)->um_e2fs; 980 if ((ufhp->ufid_ino < EXT2_FIRSTINO && ufhp->ufid_ino != EXT2_ROOTINO) || 981 ufhp->ufid_ino > fs->e2fs_ncg * fs->e2fs.e2fs_ipg) 982 return (ESTALE); 983 984 if ((error = VFS_VGET(mp, ufhp->ufid_ino, &nvp)) != 0) { 985 *vpp = NULLVP; 986 return (error); 987 } 988 ip = VTOI(nvp); 989 if (ip->i_e2fs_mode == 0 || ip->i_e2fs_dtime != 0 || 990 ip->i_e2fs_gen != ufhp->ufid_gen) { 991 vput(nvp); 992 *vpp = NULLVP; 993 return (ESTALE); 994 } 995 *vpp = nvp; 996 return (0); 997 } 998 999 /* 1000 * Vnode pointer to File handle 1001 */ 1002 /* ARGSUSED */ 1003 int 1004 ext2fs_vptofh(struct vnode *vp, struct fid *fhp) 1005 { 1006 struct inode *ip; 1007 struct ufid *ufhp; 1008 1009 ip = VTOI(vp); 1010 ufhp = (struct ufid *)fhp; 1011 ufhp->ufid_len = sizeof(struct ufid); 1012 ufhp->ufid_ino = ip->i_number; 1013 ufhp->ufid_gen = ip->i_e2fs_gen; 1014 return (0); 1015 } 1016 1017 /* 1018 * no sysctl for ext2fs 1019 */ 1020 1021 int 1022 ext2fs_sysctl(int *name, u_int namelen, void *oldp, size_t *oldlenp, 1023 void *newp, size_t newlen, struct proc *p) 1024 { 1025 return (EOPNOTSUPP); 1026 } 1027 1028 /* 1029 * Write a superblock and associated information back to disk. 1030 */ 1031 int 1032 ext2fs_sbupdate(struct ufsmount *mp, int waitfor) 1033 { 1034 struct m_ext2fs *fs = mp->um_e2fs; 1035 struct buf *bp; 1036 int error = 0; 1037 1038 bp = getblk(mp->um_devvp, SBLOCK, SBSIZE, 0, INFSLP); 1039 e2fs_sbsave(&fs->e2fs, (struct ext2fs *) bp->b_data); 1040 if (waitfor == MNT_WAIT) 1041 error = bwrite(bp); 1042 else 1043 bawrite(bp); 1044 fs->e2fs_fmod = 0; 1045 return (error); 1046 } 1047 1048 int 1049 ext2fs_cgupdate(struct ufsmount *mp, int waitfor) 1050 { 1051 struct m_ext2fs *fs = mp->um_e2fs; 1052 struct buf *bp; 1053 int i, error = 0, allerror = 0; 1054 1055 allerror = ext2fs_sbupdate(mp, waitfor); 1056 for (i = 0; i < fs->e2fs_ngdb; i++) { 1057 bp = getblk(mp->um_devvp, fsbtodb(fs, ((fs->e2fs_bsize>1024)?0:1)+i+1), 1058 fs->e2fs_bsize, 0, INFSLP); 1059 e2fs_cgsave(&fs->e2fs_gd[i* fs->e2fs_bsize / sizeof(struct ext2_gd)], (struct ext2_gd*)bp->b_data, fs->e2fs_bsize); 1060 if (waitfor == MNT_WAIT) 1061 error = bwrite(bp); 1062 else 1063 bawrite(bp); 1064 } 1065 1066 if (!allerror && error) 1067 allerror = error; 1068 return (allerror); 1069 } 1070 1071 /* This is called before the superblock is copied. Watch out for endianity! */ 1072 static int 1073 e2fs_sbcheck(struct ext2fs *fs, int ronly) 1074 { 1075 u_int32_t mask, tmp; 1076 int i; 1077 1078 tmp = letoh16(fs->e2fs_magic); 1079 if (tmp != E2FS_MAGIC) { 1080 printf("ext2fs: wrong magic number 0x%x\n", tmp); 1081 return (EIO); /* XXX needs translation */ 1082 } 1083 1084 tmp = letoh32(fs->e2fs_log_bsize); 1085 if (tmp > 2) { 1086 /* skewed log(block size): 1024 -> 0 | 2048 -> 1 | 4096 -> 2 */ 1087 tmp += 10; 1088 printf("ext2fs: wrong log2(block size) %d\n", tmp); 1089 return (EIO); /* XXX needs translation */ 1090 } 1091 1092 if (fs->e2fs_bpg == 0) { 1093 printf("ext2fs: zero blocks per group\n"); 1094 return (EIO); 1095 } 1096 1097 tmp = letoh32(fs->e2fs_rev); 1098 if (tmp > E2FS_REV1) { 1099 printf("ext2fs: wrong revision number 0x%x\n", tmp); 1100 return (EIO); /* XXX needs translation */ 1101 } 1102 else if (tmp == E2FS_REV0) 1103 return (0); 1104 1105 tmp = letoh32(fs->e2fs_first_ino); 1106 if (tmp != EXT2_FIRSTINO) { 1107 printf("ext2fs: first inode at 0x%x\n", tmp); 1108 return (EINVAL); /* XXX needs translation */ 1109 } 1110 1111 tmp = letoh32(fs->e2fs_features_incompat); 1112 mask = tmp & ~(EXT2F_INCOMPAT_SUPP | EXT4F_RO_INCOMPAT_SUPP); 1113 if (mask) { 1114 printf("ext2fs: unsupported incompat features: "); 1115 for (i = 0; i < nitems(incompat); i++) 1116 if (mask & incompat[i].mask) 1117 printf("%s ", incompat[i].name); 1118 printf("\n"); 1119 return (EINVAL); /* XXX needs translation */ 1120 } 1121 1122 if (!ronly && (tmp & EXT4F_RO_INCOMPAT_SUPP)) { 1123 printf("ext4fs: only read-only support right now\n"); 1124 return (EROFS); /* XXX needs translation */ 1125 } 1126 1127 if (tmp & EXT2F_INCOMPAT_RECOVER) { 1128 printf("ext2fs: your file system says it needs recovery\n"); 1129 if (!ronly) 1130 return (EROFS); /* XXX needs translation */ 1131 } 1132 1133 tmp = letoh32(fs->e2fs_features_rocompat) & ~EXT2F_ROCOMPAT_SUPP; 1134 if (!ronly && tmp) { 1135 printf("ext2fs: unsupported R/O compat features: "); 1136 for (i = 0; i < nitems(ro_compat); i++) 1137 if (tmp & ro_compat[i].mask) 1138 printf("%s ", ro_compat[i].name); 1139 printf("\n"); 1140 return (EROFS); /* XXX needs translation */ 1141 } 1142 1143 return (0); 1144 } 1145