1 /*- 2 * modified for EXT2FS support in Lites 1.1 3 * 4 * Aug 1995, Godmar Back (gback@cs.utah.edu) 5 * University of Utah, Department of Computer Science 6 */ 7 /*- 8 * Copyright (c) 1989, 1991, 1993, 1994 9 * The Regents of the University of California. All rights reserved. 10 * 11 * Redistribution and use in source and binary forms, with or without 12 * modification, are permitted provided that the following conditions 13 * are met: 14 * 1. Redistributions of source code must retain the above copyright 15 * notice, this list of conditions and the following disclaimer. 16 * 2. Redistributions in binary form must reproduce the above copyright 17 * notice, this list of conditions and the following disclaimer in the 18 * documentation and/or other materials provided with the distribution. 19 * 4. Neither the name of the University nor the names of its contributors 20 * may be used to endorse or promote products derived from this software 21 * without specific prior written permission. 22 * 23 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 24 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 25 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 26 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 27 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 28 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 29 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 30 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 31 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 32 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 33 * SUCH DAMAGE. 34 * 35 * @(#)ffs_vfsops.c 8.8 (Berkeley) 4/18/94 36 * $FreeBSD$ 37 */ 38 39 #include <sys/param.h> 40 #include <sys/systm.h> 41 #include <sys/namei.h> 42 #include <sys/priv.h> 43 #include <sys/proc.h> 44 #include <sys/kernel.h> 45 #include <sys/vnode.h> 46 #include <sys/mount.h> 47 #include <sys/bio.h> 48 #include <sys/buf.h> 49 #include <sys/conf.h> 50 #include <sys/fcntl.h> 51 #include <sys/malloc.h> 52 #include <sys/stat.h> 53 #include <sys/mutex.h> 54 55 #include <geom/geom.h> 56 #include <geom/geom_vfs.h> 57 58 #include <fs/ext2fs/ext2_mount.h> 59 #include <fs/ext2fs/inode.h> 60 61 #include <fs/ext2fs/fs.h> 62 #include <fs/ext2fs/ext2_extern.h> 63 #include <fs/ext2fs/ext2fs.h> 64 65 static int ext2_flushfiles(struct mount *mp, int flags, struct thread *td); 66 static int ext2_mountfs(struct vnode *, struct mount *); 67 static int ext2_reload(struct mount *mp, struct thread *td); 68 static int ext2_sbupdate(struct ext2mount *, int); 69 static int ext2_cgupdate(struct ext2mount *, int); 70 static vfs_unmount_t ext2_unmount; 71 static vfs_root_t ext2_root; 72 static vfs_statfs_t ext2_statfs; 73 static vfs_sync_t ext2_sync; 74 static vfs_vget_t ext2_vget; 75 static vfs_fhtovp_t ext2_fhtovp; 76 static vfs_mount_t ext2_mount; 77 78 MALLOC_DEFINE(M_EXT2NODE, "ext2_node", "EXT2 vnode private part"); 79 static MALLOC_DEFINE(M_EXT2MNT, "ext2_mount", "EXT2 mount structure"); 80 81 static struct vfsops ext2fs_vfsops = { 82 .vfs_fhtovp = ext2_fhtovp, 83 .vfs_mount = ext2_mount, 84 .vfs_root = ext2_root, /* root inode via vget */ 85 .vfs_statfs = ext2_statfs, 86 .vfs_sync = ext2_sync, 87 .vfs_unmount = ext2_unmount, 88 .vfs_vget = ext2_vget, 89 }; 90 91 VFS_SET(ext2fs_vfsops, ext2fs, 0); 92 93 static int ext2_check_sb_compat(struct ext2fs *es, struct cdev *dev, 94 int ronly); 95 static int compute_sb_data(struct vnode * devvp, 96 struct ext2fs * es, struct m_ext2fs * fs); 97 98 static const char *ext2_opts[] = { "from", "export", "acls", "noexec", 99 "noatime", "union", "suiddir", "multilabel", "nosymfollow", 100 "noclusterr", "noclusterw", "force", NULL }; 101 102 /* 103 * VFS Operations. 104 * 105 * mount system call 106 */ 107 static int 108 ext2_mount(struct mount *mp) 109 { 110 struct vfsoptlist *opts; 111 struct vnode *devvp; 112 struct thread *td; 113 struct ext2mount *ump = 0; 114 struct m_ext2fs *fs; 115 struct nameidata nd, *ndp = &nd; 116 accmode_t accmode; 117 char *path, *fspec; 118 int error, flags, len; 119 120 td = curthread; 121 opts = mp->mnt_optnew; 122 123 if (vfs_filteropt(opts, ext2_opts)) 124 return (EINVAL); 125 126 vfs_getopt(opts, "fspath", (void **)&path, NULL); 127 /* Double-check the length of path.. */ 128 if (strlen(path) >= MAXMNTLEN - 1) 129 return (ENAMETOOLONG); 130 131 fspec = NULL; 132 error = vfs_getopt(opts, "from", (void **)&fspec, &len); 133 if (!error && fspec[len - 1] != '\0') 134 return (EINVAL); 135 136 /* 137 * If updating, check whether changing from read-only to 138 * read/write; if there is no device name, that's all we do. 139 */ 140 if (mp->mnt_flag & MNT_UPDATE) { 141 ump = VFSTOEXT2(mp); 142 fs = ump->um_e2fs; 143 error = 0; 144 if (fs->e2fs_ronly == 0 && 145 vfs_flagopt(opts, "ro", NULL, 0)) { 146 error = VFS_SYNC(mp, MNT_WAIT); 147 if (error) 148 return (error); 149 flags = WRITECLOSE; 150 if (mp->mnt_flag & MNT_FORCE) 151 flags |= FORCECLOSE; 152 error = ext2_flushfiles(mp, flags, td); 153 if ( error == 0 && fs->e2fs_wasvalid && ext2_cgupdate(ump, MNT_WAIT) == 0) { 154 fs->e2fs->e2fs_state |= E2FS_ISCLEAN; 155 ext2_sbupdate(ump, MNT_WAIT); 156 } 157 fs->e2fs_ronly = 1; 158 vfs_flagopt(opts, "ro", &mp->mnt_flag, MNT_RDONLY); 159 DROP_GIANT(); 160 g_topology_lock(); 161 g_access(ump->um_cp, 0, -1, 0); 162 g_topology_unlock(); 163 PICKUP_GIANT(); 164 } 165 if (!error && (mp->mnt_flag & MNT_RELOAD)) 166 error = ext2_reload(mp, td); 167 if (error) 168 return (error); 169 devvp = ump->um_devvp; 170 if (fs->e2fs_ronly && !vfs_flagopt(opts, "ro", NULL, 0)) { 171 if (ext2_check_sb_compat(fs->e2fs, devvp->v_rdev, 0)) 172 return (EPERM); 173 174 /* 175 * If upgrade to read-write by non-root, then verify 176 * that user has necessary permissions on the device. 177 */ 178 vn_lock(devvp, LK_EXCLUSIVE | LK_RETRY); 179 error = VOP_ACCESS(devvp, VREAD | VWRITE, 180 td->td_ucred, td); 181 if (error) 182 error = priv_check(td, PRIV_VFS_MOUNT_PERM); 183 if (error) { 184 VOP_UNLOCK(devvp, 0); 185 return (error); 186 } 187 VOP_UNLOCK(devvp, 0); 188 DROP_GIANT(); 189 g_topology_lock(); 190 error = g_access(ump->um_cp, 0, 1, 0); 191 g_topology_unlock(); 192 PICKUP_GIANT(); 193 if (error) 194 return (error); 195 196 if ((fs->e2fs->e2fs_state & E2FS_ISCLEAN) == 0 || 197 (fs->e2fs->e2fs_state & E2FS_ERRORS)) { 198 if (mp->mnt_flag & MNT_FORCE) { 199 printf( 200 "WARNING: %s was not properly dismounted\n", fs->e2fs_fsmnt); 201 } else { 202 printf( 203 "WARNING: R/W mount of %s denied. Filesystem is not clean - run fsck\n", 204 fs->e2fs_fsmnt); 205 return (EPERM); 206 } 207 } 208 fs->e2fs->e2fs_state &= ~E2FS_ISCLEAN; 209 (void)ext2_cgupdate(ump, MNT_WAIT); 210 fs->e2fs_ronly = 0; 211 MNT_ILOCK(mp); 212 mp->mnt_flag &= ~MNT_RDONLY; 213 MNT_IUNLOCK(mp); 214 } 215 if (vfs_flagopt(opts, "export", NULL, 0)) { 216 /* Process export requests in vfs_mount.c. */ 217 return (error); 218 } 219 } 220 221 /* 222 * Not an update, or updating the name: look up the name 223 * and verify that it refers to a sensible disk device. 224 */ 225 if (fspec == NULL) 226 return (EINVAL); 227 NDINIT(ndp, LOOKUP, FOLLOW | LOCKLEAF, UIO_SYSSPACE, fspec, td); 228 if ((error = namei(ndp)) != 0) 229 return (error); 230 NDFREE(ndp, NDF_ONLY_PNBUF); 231 devvp = ndp->ni_vp; 232 233 if (!vn_isdisk(devvp, &error)) { 234 vput(devvp); 235 return (error); 236 } 237 238 /* 239 * If mount by non-root, then verify that user has necessary 240 * permissions on the device. 241 * 242 * XXXRW: VOP_ACCESS() enough? 243 */ 244 accmode = VREAD; 245 if ((mp->mnt_flag & MNT_RDONLY) == 0) 246 accmode |= VWRITE; 247 error = VOP_ACCESS(devvp, accmode, td->td_ucred, td); 248 if (error) 249 error = priv_check(td, PRIV_VFS_MOUNT_PERM); 250 if (error) { 251 vput(devvp); 252 return (error); 253 } 254 255 if ((mp->mnt_flag & MNT_UPDATE) == 0) { 256 error = ext2_mountfs(devvp, mp); 257 } else { 258 if (devvp != ump->um_devvp) { 259 vput(devvp); 260 return (EINVAL); /* needs translation */ 261 } else 262 vput(devvp); 263 } 264 if (error) { 265 vrele(devvp); 266 return (error); 267 } 268 ump = VFSTOEXT2(mp); 269 fs = ump->um_e2fs; 270 271 /* 272 * Note that this strncpy() is ok because of a check at the start 273 * of ext2_mount(). 274 */ 275 strncpy(fs->e2fs_fsmnt, path, MAXMNTLEN); 276 fs->e2fs_fsmnt[MAXMNTLEN - 1] = '\0'; 277 vfs_mountedfrom(mp, fspec); 278 return (0); 279 } 280 281 static int 282 ext2_check_sb_compat(struct ext2fs *es, struct cdev *dev, int ronly) 283 { 284 285 if (es->e2fs_magic != E2FS_MAGIC) { 286 printf("ext2fs: %s: wrong magic number %#x (expected %#x)\n", 287 devtoname(dev), es->e2fs_magic, E2FS_MAGIC); 288 return (1); 289 } 290 if (es->e2fs_rev > E2FS_REV0) { 291 if (es->e2fs_features_incompat & ~EXT2F_INCOMPAT_SUPP) { 292 printf( 293 "WARNING: mount of %s denied due to unsupported optional features\n", 294 devtoname(dev)); 295 return (1); 296 } 297 if (!ronly && 298 (es->e2fs_features_rocompat & ~EXT2F_ROCOMPAT_SUPP)) { 299 printf("WARNING: R/W mount of %s denied due to " 300 "unsupported optional features\n", devtoname(dev)); 301 return (1); 302 } 303 } 304 return (0); 305 } 306 307 /* 308 * This computes the fields of the ext2_sb_info structure from the 309 * data in the ext2_super_block structure read in. 310 */ 311 static int 312 compute_sb_data(struct vnode *devvp, struct ext2fs *es, 313 struct m_ext2fs *fs) 314 { 315 int db_count, error; 316 int i; 317 int logic_sb_block = 1; /* XXX for now */ 318 struct buf *bp; 319 320 fs->e2fs_bsize = EXT2_MIN_BLOCK_SIZE << es->e2fs_log_bsize; 321 fs->e2fs_bshift = EXT2_MIN_BLOCK_LOG_SIZE + es->e2fs_log_bsize; 322 fs->e2fs_fsbtodb = es->e2fs_log_bsize + 1; 323 fs->e2fs_qbmask = fs->e2fs_bsize - 1; 324 fs->e2fs_blocksize_bits = es->e2fs_log_bsize + 10; 325 fs->e2fs_fsize = EXT2_MIN_FRAG_SIZE << es->e2fs_log_fsize; 326 if (fs->e2fs_fsize) 327 fs->e2fs_fpb = fs->e2fs_bsize / fs->e2fs_fsize; 328 fs->e2fs_bpg = es->e2fs_bpg; 329 fs->e2fs_fpg = es->e2fs_fpg; 330 fs->e2fs_ipg = es->e2fs_ipg; 331 if (es->e2fs_rev == E2FS_REV0) { 332 fs->e2fs_first_inode = E2FS_REV0_FIRST_INO; 333 fs->e2fs_isize = E2FS_REV0_INODE_SIZE ; 334 } else { 335 fs->e2fs_first_inode = es->e2fs_first_ino; 336 fs->e2fs_isize = es->e2fs_inode_size; 337 338 /* 339 * Simple sanity check for superblock inode size value. 340 */ 341 if (fs->e2fs_isize < E2FS_REV0_INODE_SIZE || 342 fs->e2fs_isize > fs->e2fs_bsize || 343 (fs->e2fs_isize & (fs->e2fs_isize - 1)) != 0) { 344 printf("EXT2-fs: invalid inode size %d\n", 345 fs->e2fs_isize); 346 return (EIO); 347 } 348 } 349 fs->e2fs_ipb = fs->e2fs_bsize / EXT2_INODE_SIZE(fs); 350 fs->e2fs_itpg = fs->e2fs_ipg /fs->e2fs_ipb; 351 fs->e2fs_descpb = fs->e2fs_bsize / sizeof (struct ext2_gd); 352 /* s_resuid / s_resgid ? */ 353 fs->e2fs_gcount = (es->e2fs_bcount - es->e2fs_first_dblock + 354 EXT2_BLOCKS_PER_GROUP(fs) - 1) / EXT2_BLOCKS_PER_GROUP(fs); 355 db_count = (fs->e2fs_gcount + EXT2_DESC_PER_BLOCK(fs) - 1) / 356 EXT2_DESC_PER_BLOCK(fs); 357 fs->e2fs_gdbcount = db_count; 358 fs->e2fs_gd = malloc(db_count * fs->e2fs_bsize, 359 M_EXT2MNT, M_WAITOK); 360 fs->e2fs_contigdirs = malloc(fs->e2fs_gcount * sizeof(*fs->e2fs_contigdirs), 361 M_EXT2MNT, M_WAITOK); 362 363 /* 364 * Adjust logic_sb_block. 365 * Godmar thinks: if the blocksize is greater than 1024, then 366 * the superblock is logically part of block zero. 367 */ 368 if(fs->e2fs_bsize > SBSIZE) 369 logic_sb_block = 0; 370 for (i = 0; i < db_count; i++) { 371 error = bread(devvp , 372 fsbtodb(fs, logic_sb_block + i + 1 ), 373 fs->e2fs_bsize, NOCRED, &bp); 374 if (error) { 375 free(fs->e2fs_gd, M_EXT2MNT); 376 brelse(bp); 377 return (error); 378 } 379 e2fs_cgload((struct ext2_gd *)bp->b_data, 380 &fs->e2fs_gd[ 381 i * fs->e2fs_bsize / sizeof(struct ext2_gd)], 382 fs->e2fs_bsize); 383 brelse(bp); 384 bp = NULL; 385 } 386 fs->e2fs_total_dir = 0; 387 for (i=0; i < fs->e2fs_gcount; i++){ 388 fs->e2fs_total_dir += fs->e2fs_gd[i].ext2bgd_ndirs; 389 fs->e2fs_contigdirs[i] = 0; 390 } 391 if (es->e2fs_rev == E2FS_REV0 || 392 (es->e2fs_features_rocompat & EXT2F_ROCOMPAT_LARGEFILE) == 0) 393 fs->e2fs_maxfilesize = 0x7fffffff; 394 else 395 fs->e2fs_maxfilesize = 0x7fffffffffffffff; 396 return (0); 397 } 398 399 /* 400 * Reload all incore data for a filesystem (used after running fsck on 401 * the root filesystem and finding things to fix). The filesystem must 402 * be mounted read-only. 403 * 404 * Things to do to update the mount: 405 * 1) invalidate all cached meta-data. 406 * 2) re-read superblock from disk. 407 * 3) re-read summary information from disk. 408 * 4) invalidate all inactive vnodes. 409 * 5) invalidate all cached file data. 410 * 6) re-read inode data for all active vnodes. 411 * XXX we are missing some steps, in particular # 3, this has to be reviewed. 412 */ 413 static int 414 ext2_reload(struct mount *mp, struct thread *td) 415 { 416 struct vnode *vp, *mvp, *devvp; 417 struct inode *ip; 418 struct buf *bp; 419 struct ext2fs *es; 420 struct m_ext2fs *fs; 421 int error; 422 423 if ((mp->mnt_flag & MNT_RDONLY) == 0) 424 return (EINVAL); 425 /* 426 * Step 1: invalidate all cached meta-data. 427 */ 428 devvp = VFSTOEXT2(mp)->um_devvp; 429 vn_lock(devvp, LK_EXCLUSIVE | LK_RETRY); 430 if (vinvalbuf(devvp, 0, 0, 0) != 0) 431 panic("ext2_reload: dirty1"); 432 VOP_UNLOCK(devvp, 0); 433 434 /* 435 * Step 2: re-read superblock from disk. 436 * constants have been adjusted for ext2 437 */ 438 if ((error = bread(devvp, SBLOCK, SBSIZE, NOCRED, &bp)) != 0) 439 return (error); 440 es = (struct ext2fs *)bp->b_data; 441 if (ext2_check_sb_compat(es, devvp->v_rdev, 0) != 0) { 442 brelse(bp); 443 return (EIO); /* XXX needs translation */ 444 } 445 fs = VFSTOEXT2(mp)->um_e2fs; 446 bcopy(bp->b_data, fs->e2fs, sizeof(struct ext2fs)); 447 448 if((error = compute_sb_data(devvp, es, fs)) != 0) { 449 brelse(bp); 450 return (error); 451 } 452 #ifdef UNKLAR 453 if (fs->fs_sbsize < SBSIZE) 454 bp->b_flags |= B_INVAL; 455 #endif 456 brelse(bp); 457 458 loop: 459 MNT_ILOCK(mp); 460 MNT_VNODE_FOREACH(vp, mp, mvp) { 461 VI_LOCK(vp); 462 if (vp->v_iflag & VI_DOOMED) { 463 VI_UNLOCK(vp); 464 continue; 465 } 466 MNT_IUNLOCK(mp); 467 /* 468 * Step 4: invalidate all cached file data. 469 */ 470 if (vget(vp, LK_EXCLUSIVE | LK_INTERLOCK, td)) { 471 MNT_VNODE_FOREACH_ABORT(mp, mvp); 472 goto loop; 473 } 474 if (vinvalbuf(vp, 0, 0, 0)) 475 panic("ext2_reload: dirty2"); 476 477 /* 478 * Step 5: re-read inode data for all active vnodes. 479 */ 480 ip = VTOI(vp); 481 error = bread(devvp, fsbtodb(fs, ino_to_fsba(fs, ip->i_number)), 482 (int)fs->e2fs_bsize, NOCRED, &bp); 483 if (error) { 484 VOP_UNLOCK(vp, 0); 485 vrele(vp); 486 MNT_VNODE_FOREACH_ABORT(mp, mvp); 487 return (error); 488 } 489 ext2_ei2i((struct ext2fs_dinode *) ((char *)bp->b_data + 490 EXT2_INODE_SIZE(fs) * ino_to_fsbo(fs, ip->i_number)), ip); 491 brelse(bp); 492 VOP_UNLOCK(vp, 0); 493 vrele(vp); 494 MNT_ILOCK(mp); 495 } 496 MNT_IUNLOCK(mp); 497 return (0); 498 } 499 500 /* 501 * Common code for mount and mountroot. 502 */ 503 static int 504 ext2_mountfs(struct vnode *devvp, struct mount *mp) 505 { 506 struct ext2mount *ump; 507 struct buf *bp; 508 struct m_ext2fs *fs; 509 struct ext2fs *es; 510 struct cdev *dev = devvp->v_rdev; 511 struct g_consumer *cp; 512 struct bufobj *bo; 513 int error; 514 int ronly; 515 516 ronly = vfs_flagopt(mp->mnt_optnew, "ro", NULL, 0); 517 /* XXX: use VOP_ACESS to check FS perms */ 518 DROP_GIANT(); 519 g_topology_lock(); 520 error = g_vfs_open(devvp, &cp, "ext2fs", ronly ? 0 : 1); 521 g_topology_unlock(); 522 PICKUP_GIANT(); 523 VOP_UNLOCK(devvp, 0); 524 if (error) 525 return (error); 526 527 /* XXX: should we check for some sectorsize or 512 instead? */ 528 if (((SBSIZE % cp->provider->sectorsize) != 0) || 529 (SBSIZE < cp->provider->sectorsize)) { 530 DROP_GIANT(); 531 g_topology_lock(); 532 g_vfs_close(cp); 533 g_topology_unlock(); 534 PICKUP_GIANT(); 535 return (EINVAL); 536 } 537 538 bo = &devvp->v_bufobj; 539 bo->bo_private = cp; 540 bo->bo_ops = g_vfs_bufops; 541 if (devvp->v_rdev->si_iosize_max != 0) 542 mp->mnt_iosize_max = devvp->v_rdev->si_iosize_max; 543 if (mp->mnt_iosize_max > MAXPHYS) 544 mp->mnt_iosize_max = MAXPHYS; 545 546 bp = NULL; 547 ump = NULL; 548 if ((error = bread(devvp, SBLOCK, SBSIZE, NOCRED, &bp)) != 0) 549 goto out; 550 es = (struct ext2fs *)bp->b_data; 551 if (ext2_check_sb_compat(es, dev, ronly) != 0) { 552 error = EINVAL; /* XXX needs translation */ 553 goto out; 554 } 555 if ((es->e2fs_state & E2FS_ISCLEAN) == 0 || 556 (es->e2fs_state & E2FS_ERRORS)) { 557 if (ronly || (mp->mnt_flag & MNT_FORCE)) { 558 printf( 559 "WARNING: Filesystem was not properly dismounted\n"); 560 } else { 561 printf( 562 "WARNING: R/W mount denied. Filesystem is not clean - run fsck\n"); 563 error = EPERM; 564 goto out; 565 } 566 } 567 ump = malloc(sizeof *ump, M_EXT2MNT, M_WAITOK); 568 bzero((caddr_t)ump, sizeof *ump); 569 570 /* 571 * I don't know whether this is the right strategy. Note that 572 * we dynamically allocate both an ext2_sb_info and an ext2_super_block 573 * while Linux keeps the super block in a locked buffer. 574 */ 575 ump->um_e2fs = malloc(sizeof(struct m_ext2fs), 576 M_EXT2MNT, M_WAITOK); 577 ump->um_e2fs->e2fs = malloc(sizeof(struct ext2fs), 578 M_EXT2MNT, M_WAITOK); 579 mtx_init(EXT2_MTX(ump), "EXT2FS", "EXT2FS Lock", MTX_DEF); 580 bcopy(es, ump->um_e2fs->e2fs, (u_int)sizeof(struct ext2fs)); 581 if ((error = compute_sb_data(devvp, ump->um_e2fs->e2fs, ump->um_e2fs))) 582 goto out; 583 584 brelse(bp); 585 bp = NULL; 586 fs = ump->um_e2fs; 587 fs->e2fs_ronly = ronly; /* ronly is set according to mnt_flags */ 588 589 /* 590 * If the fs is not mounted read-only, make sure the super block is 591 * always written back on a sync(). 592 */ 593 fs->e2fs_wasvalid = fs->e2fs->e2fs_state & E2FS_ISCLEAN ? 1 : 0; 594 if (ronly == 0) { 595 fs->e2fs_fmod = 1; /* mark it modified */ 596 fs->e2fs->e2fs_state &= ~E2FS_ISCLEAN; /* set fs invalid */ 597 } 598 mp->mnt_data = ump; 599 mp->mnt_stat.f_fsid.val[0] = dev2udev(dev); 600 mp->mnt_stat.f_fsid.val[1] = mp->mnt_vfc->vfc_typenum; 601 mp->mnt_maxsymlinklen = EXT2_MAXSYMLINKLEN; 602 MNT_ILOCK(mp); 603 mp->mnt_flag |= MNT_LOCAL; 604 MNT_IUNLOCK(mp); 605 ump->um_mountp = mp; 606 ump->um_dev = dev; 607 ump->um_devvp = devvp; 608 ump->um_bo = &devvp->v_bufobj; 609 ump->um_cp = cp; 610 611 /* 612 * Setting those two parameters allowed us to use 613 * ufs_bmap w/o changse! 614 */ 615 ump->um_nindir = EXT2_ADDR_PER_BLOCK(fs); 616 ump->um_bptrtodb = fs->e2fs->e2fs_log_bsize + 1; 617 ump->um_seqinc = EXT2_FRAGS_PER_BLOCK(fs); 618 if (ronly == 0) 619 ext2_sbupdate(ump, MNT_WAIT); 620 /* 621 * Initialize filesystem stat information in mount struct. 622 */ 623 MNT_ILOCK(mp); 624 mp->mnt_kern_flag |= MNTK_MPSAFE | MNTK_LOOKUP_SHARED | 625 MNTK_EXTENDED_SHARED; 626 MNT_IUNLOCK(mp); 627 return (0); 628 out: 629 if (bp) 630 brelse(bp); 631 if (cp != NULL) { 632 DROP_GIANT(); 633 g_topology_lock(); 634 g_vfs_close(cp); 635 g_topology_unlock(); 636 PICKUP_GIANT(); 637 } 638 if (ump) { 639 mtx_destroy(EXT2_MTX(ump)); 640 free(ump->um_e2fs->e2fs_gd, M_EXT2MNT); 641 free(ump->um_e2fs->e2fs_contigdirs, M_EXT2MNT); 642 free(ump->um_e2fs->e2fs, M_EXT2MNT); 643 free(ump->um_e2fs, M_EXT2MNT); 644 free(ump, M_EXT2MNT); 645 mp->mnt_data = NULL; 646 } 647 return (error); 648 } 649 650 /* 651 * Unmount system call. 652 */ 653 static int 654 ext2_unmount(struct mount *mp, int mntflags) 655 { 656 struct ext2mount *ump; 657 struct m_ext2fs *fs; 658 int error, flags, ronly; 659 660 flags = 0; 661 if (mntflags & MNT_FORCE) { 662 if (mp->mnt_flag & MNT_ROOTFS) 663 return (EINVAL); 664 flags |= FORCECLOSE; 665 } 666 if ((error = ext2_flushfiles(mp, flags, curthread)) != 0) 667 return (error); 668 ump = VFSTOEXT2(mp); 669 fs = ump->um_e2fs; 670 ronly = fs->e2fs_ronly; 671 if (ronly == 0 && ext2_cgupdate(ump, MNT_WAIT) == 0) { 672 if (fs->e2fs_wasvalid) 673 fs->e2fs->e2fs_state |= E2FS_ISCLEAN; 674 ext2_sbupdate(ump, MNT_WAIT); 675 } 676 677 DROP_GIANT(); 678 g_topology_lock(); 679 g_vfs_close(ump->um_cp); 680 g_topology_unlock(); 681 PICKUP_GIANT(); 682 vrele(ump->um_devvp); 683 free(fs->e2fs_gd, M_EXT2MNT); 684 free(fs->e2fs_contigdirs, M_EXT2MNT); 685 free(fs->e2fs, M_EXT2MNT); 686 free(fs, M_EXT2MNT); 687 free(ump, M_EXT2MNT); 688 mp->mnt_data = NULL; 689 MNT_ILOCK(mp); 690 mp->mnt_flag &= ~MNT_LOCAL; 691 MNT_IUNLOCK(mp); 692 return (error); 693 } 694 695 /* 696 * Flush out all the files in a filesystem. 697 */ 698 static int 699 ext2_flushfiles(struct mount *mp, int flags, struct thread *td) 700 { 701 int error; 702 703 error = vflush(mp, 0, flags, td); 704 return (error); 705 } 706 /* 707 * Get file system statistics. 708 */ 709 int 710 ext2_statfs(struct mount *mp, struct statfs *sbp) 711 { 712 struct ext2mount *ump; 713 struct m_ext2fs *fs; 714 uint32_t overhead, overhead_per_group, ngdb; 715 int i, ngroups; 716 717 ump = VFSTOEXT2(mp); 718 fs = ump->um_e2fs; 719 if (fs->e2fs->e2fs_magic != E2FS_MAGIC) 720 panic("ext2fs_statvfs"); 721 722 /* 723 * Compute the overhead (FS structures) 724 */ 725 overhead_per_group = 726 1 /* block bitmap */ + 727 1 /* inode bitmap */ + 728 fs->e2fs_itpg; 729 overhead = fs->e2fs->e2fs_first_dblock + 730 fs->e2fs_gcount * overhead_per_group; 731 if (fs->e2fs->e2fs_rev > E2FS_REV0 && 732 fs->e2fs->e2fs_features_rocompat & EXT2F_ROCOMPAT_SPARSESUPER) { 733 for (i = 0, ngroups = 0; i < fs->e2fs_gcount; i++) { 734 if (cg_has_sb(i)) 735 ngroups++; 736 } 737 } else { 738 ngroups = fs->e2fs_gcount; 739 } 740 ngdb = fs->e2fs_gdbcount; 741 if (fs->e2fs->e2fs_rev > E2FS_REV0 && 742 fs->e2fs->e2fs_features_compat & EXT2F_COMPAT_RESIZE) 743 ngdb += fs->e2fs->e2fs_reserved_ngdb; 744 overhead += ngroups * (1 /* superblock */ + ngdb); 745 746 sbp->f_bsize = EXT2_FRAG_SIZE(fs); 747 sbp->f_iosize = EXT2_BLOCK_SIZE(fs); 748 sbp->f_blocks = fs->e2fs->e2fs_bcount - overhead; 749 sbp->f_bfree = fs->e2fs->e2fs_fbcount; 750 sbp->f_bavail = sbp->f_bfree - fs->e2fs->e2fs_rbcount; 751 sbp->f_files = fs->e2fs->e2fs_icount; 752 sbp->f_ffree = fs->e2fs->e2fs_ficount; 753 return (0); 754 } 755 756 /* 757 * Go through the disk queues to initiate sandbagged IO; 758 * go through the inodes to write those that have been modified; 759 * initiate the writing of the super block if it has been modified. 760 * 761 * Note: we are always called with the filesystem marked `MPBUSY'. 762 */ 763 static int 764 ext2_sync(struct mount *mp, int waitfor) 765 { 766 struct vnode *mvp, *vp; 767 struct thread *td; 768 struct inode *ip; 769 struct ext2mount *ump = VFSTOEXT2(mp); 770 struct m_ext2fs *fs; 771 int error, allerror = 0; 772 773 td = curthread; 774 fs = ump->um_e2fs; 775 if (fs->e2fs_fmod != 0 && fs->e2fs_ronly != 0) { /* XXX */ 776 printf("fs = %s\n", fs->e2fs_fsmnt); 777 panic("ext2_sync: rofs mod"); 778 } 779 780 /* 781 * Write back each (modified) inode. 782 */ 783 MNT_ILOCK(mp); 784 loop: 785 MNT_VNODE_FOREACH(vp, mp, mvp) { 786 VI_LOCK(vp); 787 if (vp->v_type == VNON || (vp->v_iflag & VI_DOOMED)) { 788 VI_UNLOCK(vp); 789 continue; 790 } 791 MNT_IUNLOCK(mp); 792 ip = VTOI(vp); 793 if ((ip->i_flag & 794 (IN_ACCESS | IN_CHANGE | IN_MODIFIED | IN_UPDATE)) == 0 && 795 (vp->v_bufobj.bo_dirty.bv_cnt == 0 || 796 waitfor == MNT_LAZY)) { 797 VI_UNLOCK(vp); 798 MNT_ILOCK(mp); 799 continue; 800 } 801 error = vget(vp, LK_EXCLUSIVE | LK_NOWAIT | LK_INTERLOCK, td); 802 if (error) { 803 MNT_ILOCK(mp); 804 if (error == ENOENT) { 805 MNT_VNODE_FOREACH_ABORT_ILOCKED(mp, mvp); 806 goto loop; 807 } 808 continue; 809 } 810 if ((error = VOP_FSYNC(vp, waitfor, td)) != 0) 811 allerror = error; 812 VOP_UNLOCK(vp, 0); 813 vrele(vp); 814 MNT_ILOCK(mp); 815 } 816 MNT_IUNLOCK(mp); 817 818 /* 819 * Force stale file system control information to be flushed. 820 */ 821 if (waitfor != MNT_LAZY) { 822 vn_lock(ump->um_devvp, LK_EXCLUSIVE | LK_RETRY); 823 if ((error = VOP_FSYNC(ump->um_devvp, waitfor, td)) != 0) 824 allerror = error; 825 VOP_UNLOCK(ump->um_devvp, 0); 826 } 827 828 /* 829 * Write back modified superblock. 830 */ 831 if (fs->e2fs_fmod != 0) { 832 fs->e2fs_fmod = 0; 833 fs->e2fs->e2fs_wtime = time_second; 834 if ((error = ext2_cgupdate(ump, waitfor)) != 0) 835 allerror = error; 836 } 837 return (allerror); 838 } 839 840 /* 841 * Look up an EXT2FS dinode number to find its incore vnode, otherwise read it 842 * in from disk. If it is in core, wait for the lock bit to clear, then 843 * return the inode locked. Detection and handling of mount points must be 844 * done by the calling routine. 845 */ 846 static int 847 ext2_vget(struct mount *mp, ino_t ino, int flags, struct vnode **vpp) 848 { 849 struct m_ext2fs *fs; 850 struct inode *ip; 851 struct ext2mount *ump; 852 struct buf *bp; 853 struct vnode *vp; 854 struct cdev *dev; 855 struct thread *td; 856 int i, error; 857 int used_blocks; 858 859 td = curthread; 860 error = vfs_hash_get(mp, ino, flags, td, vpp, NULL, NULL); 861 if (error || *vpp != NULL) 862 return (error); 863 864 ump = VFSTOEXT2(mp); 865 dev = ump->um_dev; 866 867 /* 868 * If this malloc() is performed after the getnewvnode() 869 * it might block, leaving a vnode with a NULL v_data to be 870 * found by ext2_sync() if a sync happens to fire right then, 871 * which will cause a panic because ext2_sync() blindly 872 * dereferences vp->v_data (as well it should). 873 */ 874 ip = malloc(sizeof(struct inode), M_EXT2NODE, M_WAITOK | M_ZERO); 875 876 /* Allocate a new vnode/inode. */ 877 if ((error = getnewvnode("ext2fs", mp, &ext2_vnodeops, &vp)) != 0) { 878 *vpp = NULL; 879 free(ip, M_EXT2NODE); 880 return (error); 881 } 882 vp->v_data = ip; 883 ip->i_vnode = vp; 884 ip->i_e2fs = fs = ump->um_e2fs; 885 ip->i_ump = ump; 886 ip->i_number = ino; 887 888 lockmgr(vp->v_vnlock, LK_EXCLUSIVE, NULL); 889 error = insmntque(vp, mp); 890 if (error != 0) { 891 free(ip, M_EXT2NODE); 892 *vpp = NULL; 893 return (error); 894 } 895 error = vfs_hash_insert(vp, ino, flags, td, vpp, NULL, NULL); 896 if (error || *vpp != NULL) 897 return (error); 898 899 /* Read in the disk contents for the inode, copy into the inode. */ 900 if ((error = bread(ump->um_devvp, fsbtodb(fs, ino_to_fsba(fs, ino)), 901 (int)fs->e2fs_bsize, NOCRED, &bp)) != 0) { 902 /* 903 * The inode does not contain anything useful, so it would 904 * be misleading to leave it on its hash chain. With mode 905 * still zero, it will be unlinked and returned to the free 906 * list by vput(). 907 */ 908 brelse(bp); 909 vput(vp); 910 *vpp = NULL; 911 return (error); 912 } 913 /* convert ext2 inode to dinode */ 914 ext2_ei2i((struct ext2fs_dinode *) ((char *)bp->b_data + EXT2_INODE_SIZE(fs) * 915 ino_to_fsbo(fs, ino)), ip); 916 ip->i_block_group = ino_to_cg(fs, ino); 917 ip->i_next_alloc_block = 0; 918 ip->i_next_alloc_goal = 0; 919 ip->i_prealloc_count = 0; 920 ip->i_prealloc_block = 0; 921 922 /* 923 * Now we want to make sure that block pointers for unused 924 * blocks are zeroed out - ext2_balloc depends on this 925 * although for regular files and directories only 926 */ 927 if(S_ISDIR(ip->i_mode) || S_ISREG(ip->i_mode)) { 928 used_blocks = (ip->i_size+fs->e2fs_bsize-1) / fs->e2fs_bsize; 929 for(i = used_blocks; i < EXT2_NDIR_BLOCKS; i++) 930 ip->i_db[i] = 0; 931 } 932 /* 933 ext2_print_inode(ip); 934 */ 935 bqrelse(bp); 936 937 /* 938 * Initialize the vnode from the inode, check for aliases. 939 * Note that the underlying vnode may have changed. 940 */ 941 if ((error = ext2_vinit(mp, &ext2_fifoops, &vp)) != 0) { 942 vput(vp); 943 *vpp = NULL; 944 return (error); 945 } 946 947 /* 948 * Finish inode initialization now that aliasing has been resolved. 949 */ 950 ip->i_devvp = ump->um_devvp; 951 952 /* 953 * Set up a generation number for this inode if it does not 954 * already have one. This should only happen on old filesystems. 955 */ 956 if (ip->i_gen == 0) { 957 ip->i_gen = random() / 2 + 1; 958 if ((vp->v_mount->mnt_flag & MNT_RDONLY) == 0) 959 ip->i_flag |= IN_MODIFIED; 960 } 961 *vpp = vp; 962 return (0); 963 } 964 965 /* 966 * File handle to vnode 967 * 968 * Have to be really careful about stale file handles: 969 * - check that the inode number is valid 970 * - call ext2_vget() to get the locked inode 971 * - check for an unallocated inode (i_mode == 0) 972 * - check that the given client host has export rights and return 973 * those rights via. exflagsp and credanonp 974 */ 975 static int 976 ext2_fhtovp(struct mount *mp, struct fid *fhp, struct vnode **vpp) 977 { 978 struct inode *ip; 979 struct ufid *ufhp; 980 struct vnode *nvp; 981 struct m_ext2fs *fs; 982 int error; 983 984 ufhp = (struct ufid *)fhp; 985 fs = VFSTOEXT2(mp)->um_e2fs; 986 if (ufhp->ufid_ino < ROOTINO || 987 ufhp->ufid_ino > fs->e2fs_gcount * fs->e2fs->e2fs_ipg) 988 return (ESTALE); 989 990 error = VFS_VGET(mp, ufhp->ufid_ino, LK_EXCLUSIVE, &nvp); 991 if (error) { 992 *vpp = NULLVP; 993 return (error); 994 } 995 ip = VTOI(nvp); 996 if (ip->i_mode == 0 || 997 ip->i_gen != ufhp->ufid_gen || ip->i_nlink <= 0) { 998 vput(nvp); 999 *vpp = NULLVP; 1000 return (ESTALE); 1001 } 1002 *vpp = nvp; 1003 vnode_create_vobject(*vpp, 0, curthread); 1004 return (0); 1005 } 1006 1007 /* 1008 * Write a superblock and associated information back to disk. 1009 */ 1010 static int 1011 ext2_sbupdate(struct ext2mount *mp, int waitfor) 1012 { 1013 struct m_ext2fs *fs = mp->um_e2fs; 1014 struct ext2fs *es = fs->e2fs; 1015 struct buf *bp; 1016 int error = 0; 1017 1018 bp = getblk(mp->um_devvp, SBLOCK, SBSIZE, 0, 0, 0); 1019 bcopy((caddr_t)es, bp->b_data, (u_int)sizeof(struct ext2fs)); 1020 if (waitfor == MNT_WAIT) 1021 error = bwrite(bp); 1022 else 1023 bawrite(bp); 1024 1025 /* 1026 * The buffers for group descriptors, inode bitmaps and block bitmaps 1027 * are not busy at this point and are (hopefully) written by the 1028 * usual sync mechanism. No need to write them here. 1029 */ 1030 return (error); 1031 } 1032 int 1033 ext2_cgupdate(struct ext2mount *mp, int waitfor) 1034 { 1035 struct m_ext2fs *fs = mp->um_e2fs; 1036 struct buf *bp; 1037 int i, error = 0, allerror = 0; 1038 1039 allerror = ext2_sbupdate(mp, waitfor); 1040 for (i = 0; i < fs->e2fs_gdbcount; i++) { 1041 bp = getblk(mp->um_devvp, fsbtodb(fs, 1042 fs->e2fs->e2fs_first_dblock + 1043 1 /* superblock */ + i), fs->e2fs_bsize, 0, 0, 0); 1044 e2fs_cgsave(&fs->e2fs_gd[ 1045 i * fs->e2fs_bsize / sizeof(struct ext2_gd)], 1046 (struct ext2_gd *)bp->b_data, fs->e2fs_bsize); 1047 if (waitfor == MNT_WAIT) 1048 error = bwrite(bp); 1049 else 1050 bawrite(bp); 1051 } 1052 1053 if (!allerror && error) 1054 allerror = error; 1055 return (allerror); 1056 } 1057 /* 1058 * Return the root of a filesystem. 1059 */ 1060 static int 1061 ext2_root(struct mount *mp, int flags, struct vnode **vpp) 1062 { 1063 struct vnode *nvp; 1064 int error; 1065 1066 error = VFS_VGET(mp, (ino_t)ROOTINO, LK_EXCLUSIVE, &nvp); 1067 if (error) 1068 return (error); 1069 *vpp = nvp; 1070 return (0); 1071 } 1072