ext2_vfsops.c revision 149720
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: head/sys/gnu/fs/ext2fs/ext2_vfsops.c 149720 2005-09-02 15:27:23Z ssouhlal $ 37 */ 38 39/*- 40 * COPYRIGHT.INFO says this has some GPL'd code from ext2_super.c in it 41 * 42 * This program is free software; you can redistribute it and/or modify 43 * it under the terms of the GNU General Public License as published by 44 * the Free Software Foundation; either version 2 of the License. 45 * 46 * This program is distributed in the hope that it will be useful, 47 * but WITHOUT ANY WARRANTY; without even the implied warranty of 48 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 49 * GNU General Public License for more details. 50 * 51 * You should have received a copy of the GNU General Public License 52 * along with this program; if not, write to the Free Software 53 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 54 * 55 */ 56 57#include <sys/param.h> 58#include <sys/systm.h> 59#include <sys/namei.h> 60#include <sys/proc.h> 61#include <sys/kernel.h> 62#include <sys/vnode.h> 63#include <sys/mount.h> 64#include <sys/bio.h> 65#include <sys/buf.h> 66#include <sys/conf.h> 67#include <sys/fcntl.h> 68#include <sys/malloc.h> 69#include <sys/stat.h> 70#include <sys/mutex.h> 71 72#include <geom/geom.h> 73#include <geom/geom_vfs.h> 74 75#include <gnu/fs/ext2fs/ext2_mount.h> 76#include <gnu/fs/ext2fs/inode.h> 77 78#include <gnu/fs/ext2fs/fs.h> 79#include <gnu/fs/ext2fs/ext2_extern.h> 80#include <gnu/fs/ext2fs/ext2_fs.h> 81#include <gnu/fs/ext2fs/ext2_fs_sb.h> 82 83static int ext2_flushfiles(struct mount *mp, int flags, struct thread *td); 84static int ext2_mountfs(struct vnode *, struct mount *, struct thread *); 85static int ext2_reload(struct mount *mp, struct thread *td); 86static int ext2_sbupdate(struct ext2mount *, int); 87 88static vfs_unmount_t ext2_unmount; 89static vfs_root_t ext2_root; 90static vfs_statfs_t ext2_statfs; 91static vfs_sync_t ext2_sync; 92static vfs_vget_t ext2_vget; 93static vfs_fhtovp_t ext2_fhtovp; 94static vfs_vptofh_t ext2_vptofh; 95static vfs_mount_t ext2_mount; 96 97MALLOC_DEFINE(M_EXT2NODE, "EXT2 node", "EXT2 vnode private part"); 98static MALLOC_DEFINE(M_EXT2MNT, "EXT2 mount", "EXT2 mount structure"); 99 100static struct vfsops ext2fs_vfsops = { 101 .vfs_fhtovp = ext2_fhtovp, 102 .vfs_mount = ext2_mount, 103 .vfs_root = ext2_root, /* root inode via vget */ 104 .vfs_statfs = ext2_statfs, 105 .vfs_sync = ext2_sync, 106 .vfs_unmount = ext2_unmount, 107 .vfs_vget = ext2_vget, 108 .vfs_vptofh = ext2_vptofh, 109}; 110 111VFS_SET(ext2fs_vfsops, ext2fs, 0); 112 113#define bsd_malloc malloc 114#define bsd_free free 115 116static int ext2_check_sb_compat(struct ext2_super_block *es, struct cdev *dev, 117 int ronly); 118static int compute_sb_data(struct vnode * devvp, 119 struct ext2_super_block * es, struct ext2_sb_info * fs); 120 121static const char *ext2_opts[] = { "from", "export" }; 122/* 123 * VFS Operations. 124 * 125 * mount system call 126 */ 127static int 128ext2_mount(mp, td) 129 struct mount *mp; 130 struct thread *td; 131{ 132 struct export_args *export; 133 struct vfsoptlist *opts; 134 struct vnode *devvp; 135 struct ext2mount *ump = 0; 136 struct ext2_sb_info *fs; 137 char *path, *fspec; 138 int error, flags, len; 139 mode_t accessmode; 140 struct nameidata nd, *ndp = &nd; 141 142 opts = mp->mnt_optnew; 143 144 if (vfs_filteropt(opts, ext2_opts)) 145 return (EINVAL); 146 147 vfs_getopt(opts, "fspath", (void **)&path, NULL); 148 /* Double-check the length of path.. */ 149 if (strlen(path) >= MAXMNTLEN - 1) 150 return (ENAMETOOLONG); 151 152 fspec = NULL; 153 error = vfs_getopt(opts, "from", (void **)&fspec, &len); 154 if (!error && fspec[len - 1] != '\0') 155 return (EINVAL); 156 157 /* 158 * If updating, check whether changing from read-only to 159 * read/write; if there is no device name, that's all we do. 160 */ 161 if (mp->mnt_flag & MNT_UPDATE) { 162 ump = VFSTOEXT2(mp); 163 fs = ump->um_e2fs; 164 error = 0; 165 if (fs->s_rd_only == 0 && 166 vfs_flagopt(opts, "ro", NULL, 0)) { 167 error = VFS_SYNC(mp, MNT_WAIT, td); 168 if (error) 169 return (error); 170 flags = WRITECLOSE; 171 if (mp->mnt_flag & MNT_FORCE) 172 flags |= FORCECLOSE; 173 if (vfs_busy(mp, LK_NOWAIT, 0, td)) 174 return (EBUSY); 175 error = ext2_flushfiles(mp, flags, td); 176 vfs_unbusy(mp, td); 177 if (!error && fs->s_wasvalid) { 178 fs->s_es->s_state |= EXT2_VALID_FS; 179 ext2_sbupdate(ump, MNT_WAIT); 180 } 181 fs->s_rd_only = 1; 182 vfs_flagopt(opts, "ro", &mp->mnt_flag, MNT_RDONLY); 183 DROP_GIANT(); 184 g_topology_lock(); 185 g_access(ump->um_cp, 0, -1, 0); 186 g_topology_unlock(); 187 PICKUP_GIANT(); 188 } 189 if (!error && (mp->mnt_flag & MNT_RELOAD)) 190 error = ext2_reload(mp, td); 191 if (error) 192 return (error); 193 devvp = ump->um_devvp; 194 if (fs->s_rd_only && !vfs_flagopt(opts, "ro", NULL, 0)) { 195 if (ext2_check_sb_compat(fs->s_es, devvp->v_rdev, 0)) 196 return (EPERM); 197 /* 198 * If upgrade to read-write by non-root, then verify 199 * that user has necessary permissions on the device. 200 */ 201 if (suser(td)) { 202 vn_lock(devvp, LK_EXCLUSIVE | LK_RETRY, td); 203 if ((error = VOP_ACCESS(devvp, VREAD | VWRITE, 204 td->td_ucred, td)) != 0) { 205 VOP_UNLOCK(devvp, 0, td); 206 return (error); 207 } 208 VOP_UNLOCK(devvp, 0, td); 209 } 210 DROP_GIANT(); 211 g_topology_lock(); 212 error = g_access(ump->um_cp, 0, 1, 0); 213 g_topology_unlock(); 214 PICKUP_GIANT(); 215 if (error) 216 return (error); 217 218 if ((fs->s_es->s_state & EXT2_VALID_FS) == 0 || 219 (fs->s_es->s_state & EXT2_ERROR_FS)) { 220 if (mp->mnt_flag & MNT_FORCE) { 221 printf( 222"WARNING: %s was not properly dismounted\n", 223 fs->fs_fsmnt); 224 } else { 225 printf( 226"WARNING: R/W mount of %s denied. Filesystem is not clean - run fsck\n", 227 fs->fs_fsmnt); 228 return (EPERM); 229 } 230 } 231 fs->s_es->s_state &= ~EXT2_VALID_FS; 232 ext2_sbupdate(ump, MNT_WAIT); 233 fs->s_rd_only = 0; 234 mp->mnt_flag &= ~MNT_RDONLY; 235 } 236 if (fspec == NULL) { 237 error = vfs_getopt(opts, "export", (void **)&export, 238 &len); 239 if (error || len != sizeof(struct export_args)) 240 return (EINVAL); 241 /* Process export requests. */ 242 return (vfs_export(mp, export)); 243 } 244 } 245 /* 246 * Not an update, or updating the name: look up the name 247 * and verify that it refers to a sensible disk device. 248 */ 249 if (fspec == NULL) 250 return (EINVAL); 251 NDINIT(ndp, LOOKUP, FOLLOW | LOCKLEAF, UIO_SYSSPACE, fspec, td); 252 if ((error = namei(ndp)) != 0) 253 return (error); 254 NDFREE(ndp, NDF_ONLY_PNBUF); 255 devvp = ndp->ni_vp; 256 257 if (!vn_isdisk(devvp, &error)) { 258 vput(devvp); 259 return (error); 260 } 261 262 /* 263 * If mount by non-root, then verify that user has necessary 264 * permissions on the device. 265 */ 266 if (suser(td)) { 267 accessmode = VREAD; 268 if ((mp->mnt_flag & MNT_RDONLY) == 0) 269 accessmode |= VWRITE; 270 if ((error = VOP_ACCESS(devvp, accessmode, td->td_ucred, td)) != 0) { 271 vput(devvp); 272 return (error); 273 } 274 } 275 276 if ((mp->mnt_flag & MNT_UPDATE) == 0) { 277 error = ext2_mountfs(devvp, mp, td); 278 } else { 279 if (devvp != ump->um_devvp) 280 error = EINVAL; /* needs translation */ 281 else 282 vput(devvp); 283 } 284 if (error) { 285 vrele(devvp); 286 return (error); 287 } 288 ump = VFSTOEXT2(mp); 289 fs = ump->um_e2fs; 290 /* 291 * Note that this strncpy() is ok because of a check at the start 292 * of ext2_mount(). 293 */ 294 strncpy(fs->fs_fsmnt, path, MAXMNTLEN); 295 fs->fs_fsmnt[MAXMNTLEN - 1] = '\0'; 296 vfs_mountedfrom(mp, fspec); 297 return (0); 298} 299 300/* 301 * checks that the data in the descriptor blocks make sense 302 * this is taken from ext2/super.c 303 */ 304static int ext2_check_descriptors (struct ext2_sb_info * sb) 305{ 306 int i; 307 int desc_block = 0; 308 unsigned long block = sb->s_es->s_first_data_block; 309 struct ext2_group_desc * gdp = NULL; 310 311 /* ext2_debug ("Checking group descriptors"); */ 312 313 for (i = 0; i < sb->s_groups_count; i++) 314 { 315 /* examine next descriptor block */ 316 if ((i % EXT2_DESC_PER_BLOCK(sb)) == 0) 317 gdp = (struct ext2_group_desc *) 318 sb->s_group_desc[desc_block++]->b_data; 319 if (gdp->bg_block_bitmap < block || 320 gdp->bg_block_bitmap >= block + EXT2_BLOCKS_PER_GROUP(sb)) 321 { 322 printf ("ext2_check_descriptors: " 323 "Block bitmap for group %d" 324 " not in group (block %lu)!\n", 325 i, (unsigned long) gdp->bg_block_bitmap); 326 return 0; 327 } 328 if (gdp->bg_inode_bitmap < block || 329 gdp->bg_inode_bitmap >= block + EXT2_BLOCKS_PER_GROUP(sb)) 330 { 331 printf ("ext2_check_descriptors: " 332 "Inode bitmap for group %d" 333 " not in group (block %lu)!\n", 334 i, (unsigned long) gdp->bg_inode_bitmap); 335 return 0; 336 } 337 if (gdp->bg_inode_table < block || 338 gdp->bg_inode_table + sb->s_itb_per_group >= 339 block + EXT2_BLOCKS_PER_GROUP(sb)) 340 { 341 printf ("ext2_check_descriptors: " 342 "Inode table for group %d" 343 " not in group (block %lu)!\n", 344 i, (unsigned long) gdp->bg_inode_table); 345 return 0; 346 } 347 block += EXT2_BLOCKS_PER_GROUP(sb); 348 gdp++; 349 } 350 return 1; 351} 352 353static int 354ext2_check_sb_compat(es, dev, ronly) 355 struct ext2_super_block *es; 356 struct cdev *dev; 357 int ronly; 358{ 359 360 if (es->s_magic != EXT2_SUPER_MAGIC) { 361 printf("ext2fs: %s: wrong magic number %#x (expected %#x)\n", 362 devtoname(dev), es->s_magic, EXT2_SUPER_MAGIC); 363 return (1); 364 } 365 if (es->s_rev_level > EXT2_GOOD_OLD_REV) { 366 if (es->s_feature_incompat & ~EXT2_FEATURE_INCOMPAT_SUPP) { 367 printf( 368"WARNING: mount of %s denied due to unsupported optional features\n", 369 devtoname(dev)); 370 return (1); 371 } 372 if (!ronly && 373 (es->s_feature_ro_compat & ~EXT2_FEATURE_RO_COMPAT_SUPP)) { 374 printf( 375"WARNING: R/W mount of %s denied due to unsupported optional features\n", 376 devtoname(dev)); 377 return (1); 378 } 379 } 380 return (0); 381} 382 383/* 384 * this computes the fields of the ext2_sb_info structure from the 385 * data in the ext2_super_block structure read in 386 */ 387static int compute_sb_data(devvp, es, fs) 388 struct vnode * devvp; 389 struct ext2_super_block * es; 390 struct ext2_sb_info * fs; 391{ 392 int db_count, error; 393 int i, j; 394 int logic_sb_block = 1; /* XXX for now */ 395 396#if 1 397#define V(v) 398#else 399#define V(v) printf(#v"= %d\n", fs->v); 400#endif 401 402 fs->s_blocksize = EXT2_MIN_BLOCK_SIZE << es->s_log_block_size; 403 V(s_blocksize) 404 fs->s_bshift = EXT2_MIN_BLOCK_LOG_SIZE + es->s_log_block_size; 405 V(s_bshift) 406 fs->s_fsbtodb = es->s_log_block_size + 1; 407 V(s_fsbtodb) 408 fs->s_qbmask = fs->s_blocksize - 1; 409 V(s_bmask) 410 fs->s_blocksize_bits = EXT2_BLOCK_SIZE_BITS(es); 411 V(s_blocksize_bits) 412 fs->s_frag_size = EXT2_MIN_FRAG_SIZE << es->s_log_frag_size; 413 V(s_frag_size) 414 if (fs->s_frag_size) 415 fs->s_frags_per_block = fs->s_blocksize / fs->s_frag_size; 416 V(s_frags_per_block) 417 fs->s_blocks_per_group = es->s_blocks_per_group; 418 V(s_blocks_per_group) 419 fs->s_frags_per_group = es->s_frags_per_group; 420 V(s_frags_per_group) 421 fs->s_inodes_per_group = es->s_inodes_per_group; 422 V(s_inodes_per_group) 423 fs->s_inodes_per_block = fs->s_blocksize / EXT2_INODE_SIZE; 424 V(s_inodes_per_block) 425 fs->s_itb_per_group = fs->s_inodes_per_group /fs->s_inodes_per_block; 426 V(s_itb_per_group) 427 fs->s_desc_per_block = fs->s_blocksize / sizeof (struct ext2_group_desc); 428 V(s_desc_per_block) 429 /* s_resuid / s_resgid ? */ 430 fs->s_groups_count = (es->s_blocks_count - 431 es->s_first_data_block + 432 EXT2_BLOCKS_PER_GROUP(fs) - 1) / 433 EXT2_BLOCKS_PER_GROUP(fs); 434 V(s_groups_count) 435 db_count = (fs->s_groups_count + EXT2_DESC_PER_BLOCK(fs) - 1) / 436 EXT2_DESC_PER_BLOCK(fs); 437 fs->s_db_per_group = db_count; 438 V(s_db_per_group) 439 440 fs->s_group_desc = bsd_malloc(db_count * sizeof (struct buf *), 441 M_EXT2MNT, M_WAITOK); 442 443 /* adjust logic_sb_block */ 444 if(fs->s_blocksize > SBSIZE) 445 /* Godmar thinks: if the blocksize is greater than 1024, then 446 the superblock is logically part of block zero. 447 */ 448 logic_sb_block = 0; 449 450 for (i = 0; i < db_count; i++) { 451 error = bread(devvp , fsbtodb(fs, logic_sb_block + i + 1), 452 fs->s_blocksize, NOCRED, &fs->s_group_desc[i]); 453 if(error) { 454 for (j = 0; j < i; j++) 455 brelse(fs->s_group_desc[j]); 456 bsd_free(fs->s_group_desc, M_EXT2MNT); 457 printf("EXT2-fs: unable to read group descriptors (%d)\n", error); 458 return EIO; 459 } 460 LCK_BUF(fs->s_group_desc[i]) 461 } 462 if(!ext2_check_descriptors(fs)) { 463 for (j = 0; j < db_count; j++) 464 ULCK_BUF(fs->s_group_desc[j]) 465 bsd_free(fs->s_group_desc, M_EXT2MNT); 466 printf("EXT2-fs: (ext2_check_descriptors failure) " 467 "unable to read group descriptors\n"); 468 return EIO; 469 } 470 471 for (i = 0; i < EXT2_MAX_GROUP_LOADED; i++) { 472 fs->s_inode_bitmap_number[i] = 0; 473 fs->s_inode_bitmap[i] = NULL; 474 fs->s_block_bitmap_number[i] = 0; 475 fs->s_block_bitmap[i] = NULL; 476 } 477 fs->s_loaded_inode_bitmaps = 0; 478 fs->s_loaded_block_bitmaps = 0; 479 if (es->s_rev_level == EXT2_GOOD_OLD_REV || (es->s_feature_ro_compat & 480 EXT2_FEATURE_RO_COMPAT_LARGE_FILE) == 0) 481 fs->fs_maxfilesize = 0x7fffffff; 482 else 483 fs->fs_maxfilesize = 0x7fffffffffffffff; 484 return 0; 485} 486 487/* 488 * Reload all incore data for a filesystem (used after running fsck on 489 * the root filesystem and finding things to fix). The filesystem must 490 * be mounted read-only. 491 * 492 * Things to do to update the mount: 493 * 1) invalidate all cached meta-data. 494 * 2) re-read superblock from disk. 495 * 3) re-read summary information from disk. 496 * 4) invalidate all inactive vnodes. 497 * 5) invalidate all cached file data. 498 * 6) re-read inode data for all active vnodes. 499 */ 500static int 501ext2_reload(struct mount *mp, struct thread *td) 502{ 503 struct vnode *vp, *nvp, *devvp; 504 struct inode *ip; 505 struct buf *bp; 506 struct ext2_super_block * es; 507 struct ext2_sb_info *fs; 508 int error; 509 510 if ((mp->mnt_flag & MNT_RDONLY) == 0) 511 return (EINVAL); 512 /* 513 * Step 1: invalidate all cached meta-data. 514 */ 515 devvp = VFSTOEXT2(mp)->um_devvp; 516 vn_lock(devvp, LK_EXCLUSIVE | LK_RETRY, td); 517 if (vinvalbuf(devvp, 0, td, 0, 0) != 0) 518 panic("ext2_reload: dirty1"); 519 VOP_UNLOCK(devvp, 0, td); 520 521 /* 522 * Step 2: re-read superblock from disk. 523 * constants have been adjusted for ext2 524 */ 525 if ((error = bread(devvp, SBLOCK, SBSIZE, NOCRED, &bp)) != 0) 526 return (error); 527 es = (struct ext2_super_block *)bp->b_data; 528 if (ext2_check_sb_compat(es, devvp->v_rdev, 0) != 0) { 529 brelse(bp); 530 return (EIO); /* XXX needs translation */ 531 } 532 fs = VFSTOEXT2(mp)->um_e2fs; 533 bcopy(bp->b_data, fs->s_es, sizeof(struct ext2_super_block)); 534 535 if((error = compute_sb_data(devvp, es, fs)) != 0) { 536 brelse(bp); 537 return error; 538 } 539#ifdef UNKLAR 540 if (fs->fs_sbsize < SBSIZE) 541 bp->b_flags |= B_INVAL; 542#endif 543 brelse(bp); 544 545loop: 546 MNT_ILOCK(mp); 547 MNT_VNODE_FOREACH(vp, mp, nvp) { 548 VI_LOCK(vp); 549 if (vp->v_iflag & VI_DOOMED) { 550 VI_UNLOCK(vp); 551 continue; 552 } 553 MNT_IUNLOCK(mp); 554 /* 555 * Step 4: invalidate all cached file data. 556 */ 557 if (vget(vp, LK_EXCLUSIVE | LK_INTERLOCK, td)) { 558 goto loop; 559 } 560 if (vinvalbuf(vp, 0, td, 0, 0)) 561 panic("ext2_reload: dirty2"); 562 /* 563 * Step 5: re-read inode data for all active vnodes. 564 */ 565 ip = VTOI(vp); 566 error = 567 bread(devvp, fsbtodb(fs, ino_to_fsba(fs, ip->i_number)), 568 (int)fs->s_blocksize, NOCRED, &bp); 569 if (error) { 570 VOP_UNLOCK(vp, 0, td); 571 vrele(vp); 572 return (error); 573 } 574 ext2_ei2i((struct ext2_inode *) ((char *)bp->b_data + 575 EXT2_INODE_SIZE * ino_to_fsbo(fs, ip->i_number)), ip); 576 brelse(bp); 577 VOP_UNLOCK(vp, 0, td); 578 vrele(vp); 579 MNT_ILOCK(mp); 580 } 581 MNT_IUNLOCK(mp); 582 return (0); 583} 584 585/* 586 * Common code for mount and mountroot 587 */ 588static int 589ext2_mountfs(devvp, mp, td) 590 struct vnode *devvp; 591 struct mount *mp; 592 struct thread *td; 593{ 594 struct ext2mount *ump; 595 struct buf *bp; 596 struct ext2_sb_info *fs; 597 struct ext2_super_block * es; 598 struct cdev *dev = devvp->v_rdev; 599 struct g_consumer *cp; 600 struct bufobj *bo; 601 int error; 602 int ronly; 603 604 ronly = vfs_flagopt(mp->mnt_optnew, "ro", NULL, 0); 605 /* XXX: use VOP_ACESS to check FS perms */ 606 DROP_GIANT(); 607 g_topology_lock(); 608 error = g_vfs_open(devvp, &cp, "ext2fs", ronly ? 0 : 1); 609 g_topology_unlock(); 610 PICKUP_GIANT(); 611 VOP_UNLOCK(devvp, 0, td); 612 if (error) 613 return (error); 614 bo = &devvp->v_bufobj; 615 bo->bo_private = cp; 616 bo->bo_ops = g_vfs_bufops; 617 if (devvp->v_rdev->si_iosize_max != 0) 618 mp->mnt_iosize_max = devvp->v_rdev->si_iosize_max; 619 if (mp->mnt_iosize_max > MAXPHYS) 620 mp->mnt_iosize_max = MAXPHYS; 621 622 bp = NULL; 623 ump = NULL; 624 if ((error = bread(devvp, SBLOCK, SBSIZE, NOCRED, &bp)) != 0) 625 goto out; 626 es = (struct ext2_super_block *)bp->b_data; 627 if (ext2_check_sb_compat(es, dev, ronly) != 0) { 628 error = EINVAL; /* XXX needs translation */ 629 goto out; 630 } 631 if ((es->s_state & EXT2_VALID_FS) == 0 || 632 (es->s_state & EXT2_ERROR_FS)) { 633 if (ronly || (mp->mnt_flag & MNT_FORCE)) { 634 printf( 635"WARNING: Filesystem was not properly dismounted\n"); 636 } else { 637 printf( 638"WARNING: R/W mount denied. Filesystem is not clean - run fsck\n"); 639 error = EPERM; 640 goto out; 641 } 642 } 643 ump = bsd_malloc(sizeof *ump, M_EXT2MNT, M_WAITOK); 644 bzero((caddr_t)ump, sizeof *ump); 645 /* I don't know whether this is the right strategy. Note that 646 we dynamically allocate both an ext2_sb_info and an ext2_super_block 647 while Linux keeps the super block in a locked buffer 648 */ 649 ump->um_e2fs = bsd_malloc(sizeof(struct ext2_sb_info), 650 M_EXT2MNT, M_WAITOK); 651 ump->um_e2fs->s_es = bsd_malloc(sizeof(struct ext2_super_block), 652 M_EXT2MNT, M_WAITOK); 653 bcopy(es, ump->um_e2fs->s_es, (u_int)sizeof(struct ext2_super_block)); 654 if ((error = compute_sb_data(devvp, ump->um_e2fs->s_es, ump->um_e2fs))) 655 goto out; 656 /* 657 * We don't free the group descriptors allocated by compute_sb_data() 658 * until ext2_unmount(). This is OK since the mount will succeed. 659 */ 660 brelse(bp); 661 bp = NULL; 662 fs = ump->um_e2fs; 663 fs->s_rd_only = ronly; /* ronly is set according to mnt_flags */ 664 /* if the fs is not mounted read-only, make sure the super block is 665 always written back on a sync() 666 */ 667 fs->s_wasvalid = fs->s_es->s_state & EXT2_VALID_FS ? 1 : 0; 668 if (ronly == 0) { 669 fs->s_dirt = 1; /* mark it modified */ 670 fs->s_es->s_state &= ~EXT2_VALID_FS; /* set fs invalid */ 671 } 672 mp->mnt_data = (qaddr_t)ump; 673 mp->mnt_stat.f_fsid.val[0] = dev2udev(dev); 674 mp->mnt_stat.f_fsid.val[1] = mp->mnt_vfc->vfc_typenum; 675 mp->mnt_maxsymlinklen = EXT2_MAXSYMLINKLEN; 676 mp->mnt_flag |= MNT_LOCAL; 677 ump->um_mountp = mp; 678 ump->um_dev = dev; 679 ump->um_devvp = devvp; 680 ump->um_bo = &devvp->v_bufobj; 681 ump->um_cp = cp; 682 /* setting those two parameters allowed us to use 683 ufs_bmap w/o changse ! 684 */ 685 ump->um_nindir = EXT2_ADDR_PER_BLOCK(fs); 686 ump->um_bptrtodb = fs->s_es->s_log_block_size + 1; 687 ump->um_seqinc = EXT2_FRAGS_PER_BLOCK(fs); 688 if (ronly == 0) 689 ext2_sbupdate(ump, MNT_WAIT); 690 return (0); 691out: 692 if (bp) 693 brelse(bp); 694 if (cp != NULL) { 695 DROP_GIANT(); 696 g_topology_lock(); 697 g_vfs_close(cp, td); 698 g_topology_unlock(); 699 PICKUP_GIANT(); 700 } 701 if (ump) { 702 bsd_free(ump->um_e2fs->s_es, M_EXT2MNT); 703 bsd_free(ump->um_e2fs, M_EXT2MNT); 704 bsd_free(ump, M_EXT2MNT); 705 mp->mnt_data = (qaddr_t)0; 706 } 707 return (error); 708} 709 710/* 711 * unmount system call 712 */ 713static int 714ext2_unmount(mp, mntflags, td) 715 struct mount *mp; 716 int mntflags; 717 struct thread *td; 718{ 719 struct ext2mount *ump; 720 struct ext2_sb_info *fs; 721 int error, flags, ronly, i; 722 723 flags = 0; 724 if (mntflags & MNT_FORCE) { 725 if (mp->mnt_flag & MNT_ROOTFS) 726 return (EINVAL); 727 flags |= FORCECLOSE; 728 } 729 if ((error = ext2_flushfiles(mp, flags, td)) != 0) 730 return (error); 731 ump = VFSTOEXT2(mp); 732 fs = ump->um_e2fs; 733 ronly = fs->s_rd_only; 734 if (ronly == 0) { 735 if (fs->s_wasvalid) 736 fs->s_es->s_state |= EXT2_VALID_FS; 737 ext2_sbupdate(ump, MNT_WAIT); 738 } 739 740 /* release buffers containing group descriptors */ 741 for(i = 0; i < fs->s_db_per_group; i++) 742 ULCK_BUF(fs->s_group_desc[i]) 743 bsd_free(fs->s_group_desc, M_EXT2MNT); 744 745 /* release cached inode/block bitmaps */ 746 for (i = 0; i < EXT2_MAX_GROUP_LOADED; i++) 747 if (fs->s_inode_bitmap[i]) 748 ULCK_BUF(fs->s_inode_bitmap[i]) 749 750 for (i = 0; i < EXT2_MAX_GROUP_LOADED; i++) 751 if (fs->s_block_bitmap[i]) 752 ULCK_BUF(fs->s_block_bitmap[i]) 753 754 DROP_GIANT(); 755 g_topology_lock(); 756 g_vfs_close(ump->um_cp, td); 757 g_topology_unlock(); 758 PICKUP_GIANT(); 759 vrele(ump->um_devvp); 760 bsd_free(fs->s_es, M_EXT2MNT); 761 bsd_free(fs, M_EXT2MNT); 762 bsd_free(ump, M_EXT2MNT); 763 mp->mnt_data = (qaddr_t)0; 764 mp->mnt_flag &= ~MNT_LOCAL; 765 return (error); 766} 767 768/* 769 * Flush out all the files in a filesystem. 770 */ 771static int 772ext2_flushfiles(mp, flags, td) 773 struct mount *mp; 774 int flags; 775 struct thread *td; 776{ 777 int error; 778 779 error = vflush(mp, 0, flags, td); 780 return (error); 781} 782 783/* 784 * Get file system statistics. 785 * taken from ext2/super.c ext2_statfs 786 */ 787static int 788ext2_statfs(mp, sbp, td) 789 struct mount *mp; 790 struct statfs *sbp; 791 struct thread *td; 792{ 793 unsigned long overhead; 794 struct ext2mount *ump; 795 struct ext2_sb_info *fs; 796 struct ext2_super_block *es; 797 int i, nsb; 798 799 ump = VFSTOEXT2(mp); 800 fs = ump->um_e2fs; 801 es = fs->s_es; 802 803 if (es->s_magic != EXT2_SUPER_MAGIC) 804 panic("ext2_statfs - magic number spoiled"); 805 806 /* 807 * Compute the overhead (FS structures) 808 */ 809 if (es->s_feature_ro_compat & EXT2_FEATURE_RO_COMPAT_SPARSE_SUPER) { 810 nsb = 0; 811 for (i = 0 ; i < fs->s_groups_count; i++) 812 if (ext2_group_sparse(i)) 813 nsb++; 814 } else 815 nsb = fs->s_groups_count; 816 overhead = es->s_first_data_block + 817 /* Superblocks and block group descriptors: */ 818 nsb * (1 + fs->s_db_per_group) + 819 /* Inode bitmap, block bitmap, and inode table: */ 820 fs->s_groups_count * (1 + 1 + fs->s_itb_per_group); 821 822 sbp->f_bsize = EXT2_FRAG_SIZE(fs); 823 sbp->f_iosize = EXT2_BLOCK_SIZE(fs); 824 sbp->f_blocks = es->s_blocks_count - overhead; 825 sbp->f_bfree = es->s_free_blocks_count; 826 sbp->f_bavail = sbp->f_bfree - es->s_r_blocks_count; 827 sbp->f_files = es->s_inodes_count; 828 sbp->f_ffree = es->s_free_inodes_count; 829 return (0); 830} 831 832/* 833 * Go through the disk queues to initiate sandbagged IO; 834 * go through the inodes to write those that have been modified; 835 * initiate the writing of the super block if it has been modified. 836 * 837 * Note: we are always called with the filesystem marked `MPBUSY'. 838 */ 839static int 840ext2_sync(mp, waitfor, td) 841 struct mount *mp; 842 int waitfor; 843 struct thread *td; 844{ 845 struct vnode *nvp, *vp; 846 struct inode *ip; 847 struct ext2mount *ump = VFSTOEXT2(mp); 848 struct ext2_sb_info *fs; 849 int error, allerror = 0; 850 851 fs = ump->um_e2fs; 852 if (fs->s_dirt != 0 && fs->s_rd_only != 0) { /* XXX */ 853 printf("fs = %s\n", fs->fs_fsmnt); 854 panic("ext2_sync: rofs mod"); 855 } 856 /* 857 * Write back each (modified) inode. 858 */ 859 MNT_ILOCK(mp); 860loop: 861 MNT_VNODE_FOREACH(vp, mp, nvp) { 862 VI_LOCK(vp); 863 if (vp->v_type == VNON || (vp->v_iflag & VI_DOOMED)) { 864 VI_UNLOCK(vp); 865 continue; 866 } 867 MNT_IUNLOCK(mp); 868 ip = VTOI(vp); 869 if ((ip->i_flag & 870 (IN_ACCESS | IN_CHANGE | IN_MODIFIED | IN_UPDATE)) == 0 && 871 (vp->v_bufobj.bo_dirty.bv_cnt == 0 || 872 waitfor == MNT_LAZY)) { 873 VI_UNLOCK(vp); 874 MNT_ILOCK(mp); 875 continue; 876 } 877 error = vget(vp, LK_EXCLUSIVE | LK_NOWAIT | LK_INTERLOCK, td); 878 if (error) { 879 MNT_ILOCK(mp); 880 if (error == ENOENT) 881 goto loop; 882 continue; 883 } 884 if ((error = VOP_FSYNC(vp, waitfor, td)) != 0) 885 allerror = error; 886 VOP_UNLOCK(vp, 0, td); 887 vrele(vp); 888 MNT_ILOCK(mp); 889 } 890 MNT_IUNLOCK(mp); 891 /* 892 * Force stale file system control information to be flushed. 893 */ 894 if (waitfor != MNT_LAZY) { 895 vn_lock(ump->um_devvp, LK_EXCLUSIVE | LK_RETRY, td); 896 if ((error = VOP_FSYNC(ump->um_devvp, waitfor, td)) != 0) 897 allerror = error; 898 VOP_UNLOCK(ump->um_devvp, 0, td); 899 } 900 /* 901 * Write back modified superblock. 902 */ 903 if (fs->s_dirt != 0) { 904 fs->s_dirt = 0; 905 fs->s_es->s_wtime = time_second; 906 if ((error = ext2_sbupdate(ump, waitfor)) != 0) 907 allerror = error; 908 } 909 return (allerror); 910} 911 912/* 913 * Look up an EXT2FS dinode number to find its incore vnode, otherwise read it 914 * in from disk. If it is in core, wait for the lock bit to clear, then 915 * return the inode locked. Detection and handling of mount points must be 916 * done by the calling routine. 917 */ 918static int 919ext2_vget(mp, ino, flags, vpp) 920 struct mount *mp; 921 ino_t ino; 922 int flags; 923 struct vnode **vpp; 924{ 925 struct ext2_sb_info *fs; 926 struct inode *ip; 927 struct ext2mount *ump; 928 struct buf *bp; 929 struct vnode *vp; 930 struct cdev *dev; 931 int i, error; 932 int used_blocks; 933 934 error = vfs_hash_get(mp, ino, flags, curthread, vpp, NULL, NULL); 935 if (error || *vpp != NULL) 936 return (error); 937 938 ump = VFSTOEXT2(mp); 939 dev = ump->um_dev; 940 941 /* 942 * If this MALLOC() is performed after the getnewvnode() 943 * it might block, leaving a vnode with a NULL v_data to be 944 * found by ext2_sync() if a sync happens to fire right then, 945 * which will cause a panic because ext2_sync() blindly 946 * dereferences vp->v_data (as well it should). 947 */ 948 ip = malloc(sizeof(struct inode), M_EXT2NODE, M_WAITOK | M_ZERO); 949 950 /* Allocate a new vnode/inode. */ 951 if ((error = getnewvnode("ext2fs", mp, &ext2_vnodeops, &vp)) != 0) { 952 *vpp = NULL; 953 free(ip, M_EXT2NODE); 954 return (error); 955 } 956 vp->v_data = ip; 957 ip->i_vnode = vp; 958 ip->i_e2fs = fs = ump->um_e2fs; 959 ip->i_number = ino; 960 961 error = vfs_hash_insert(vp, ino, flags, curthread, vpp, NULL, NULL); 962 if (error || *vpp != NULL) 963 return (error); 964 965 /* Read in the disk contents for the inode, copy into the inode. */ 966#if 0 967printf("ext2_vget(%d) dbn= %d ", ino, fsbtodb(fs, ino_to_fsba(fs, ino))); 968#endif 969 if ((error = bread(ump->um_devvp, fsbtodb(fs, ino_to_fsba(fs, ino)), 970 (int)fs->s_blocksize, NOCRED, &bp)) != 0) { 971 /* 972 * The inode does not contain anything useful, so it would 973 * be misleading to leave it on its hash chain. With mode 974 * still zero, it will be unlinked and returned to the free 975 * list by vput(). 976 */ 977 vput(vp); 978 brelse(bp); 979 *vpp = NULL; 980 return (error); 981 } 982 /* convert ext2 inode to dinode */ 983 ext2_ei2i((struct ext2_inode *) ((char *)bp->b_data + EXT2_INODE_SIZE * 984 ino_to_fsbo(fs, ino)), ip); 985 ip->i_block_group = ino_to_cg(fs, ino); 986 ip->i_next_alloc_block = 0; 987 ip->i_next_alloc_goal = 0; 988 ip->i_prealloc_count = 0; 989 ip->i_prealloc_block = 0; 990 /* now we want to make sure that block pointers for unused 991 blocks are zeroed out - ext2_balloc depends on this 992 although for regular files and directories only 993 */ 994 if(S_ISDIR(ip->i_mode) || S_ISREG(ip->i_mode)) { 995 used_blocks = (ip->i_size+fs->s_blocksize-1) / fs->s_blocksize; 996 for(i = used_blocks; i < EXT2_NDIR_BLOCKS; i++) 997 ip->i_db[i] = 0; 998 } 999/* 1000 ext2_print_inode(ip); 1001*/ 1002 brelse(bp); 1003 1004 /* 1005 * Initialize the vnode from the inode, check for aliases. 1006 * Note that the underlying vnode may have changed. 1007 */ 1008 if ((error = ext2_vinit(mp, &ext2_fifoops, &vp)) != 0) { 1009 vput(vp); 1010 *vpp = NULL; 1011 return (error); 1012 } 1013 /* 1014 * Finish inode initialization now that aliasing has been resolved. 1015 */ 1016 ip->i_devvp = ump->um_devvp; 1017 /* 1018 * Set up a generation number for this inode if it does not 1019 * already have one. This should only happen on old filesystems. 1020 */ 1021 if (ip->i_gen == 0) { 1022 ip->i_gen = random() / 2 + 1; 1023 if ((vp->v_mount->mnt_flag & MNT_RDONLY) == 0) 1024 ip->i_flag |= IN_MODIFIED; 1025 } 1026 *vpp = vp; 1027 return (0); 1028} 1029 1030/* 1031 * File handle to vnode 1032 * 1033 * Have to be really careful about stale file handles: 1034 * - check that the inode number is valid 1035 * - call ext2_vget() to get the locked inode 1036 * - check for an unallocated inode (i_mode == 0) 1037 * - check that the given client host has export rights and return 1038 * those rights via. exflagsp and credanonp 1039 */ 1040static int 1041ext2_fhtovp(mp, fhp, vpp) 1042 struct mount *mp; 1043 struct fid *fhp; 1044 struct vnode **vpp; 1045{ 1046 struct inode *ip; 1047 struct ufid *ufhp; 1048 struct vnode *nvp; 1049 struct ext2_sb_info *fs; 1050 int error; 1051 1052 ufhp = (struct ufid *)fhp; 1053 fs = VFSTOEXT2(mp)->um_e2fs; 1054 if (ufhp->ufid_ino < ROOTINO || 1055 ufhp->ufid_ino > fs->s_groups_count * fs->s_es->s_inodes_per_group) 1056 return (ESTALE); 1057 1058 error = VFS_VGET(mp, ufhp->ufid_ino, LK_EXCLUSIVE, &nvp); 1059 if (error) { 1060 *vpp = NULLVP; 1061 return (error); 1062 } 1063 ip = VTOI(nvp); 1064 if (ip->i_mode == 0 || 1065 ip->i_gen != ufhp->ufid_gen || ip->i_nlink <= 0) { 1066 vput(nvp); 1067 *vpp = NULLVP; 1068 return (ESTALE); 1069 } 1070 *vpp = nvp; 1071 vnode_create_vobject(*vpp, 0, curthread); 1072 return (0); 1073} 1074 1075/* 1076 * Vnode pointer to File handle 1077 */ 1078/* ARGSUSED */ 1079static int 1080ext2_vptofh(vp, fhp) 1081 struct vnode *vp; 1082 struct fid *fhp; 1083{ 1084 struct inode *ip; 1085 struct ufid *ufhp; 1086 1087 ip = VTOI(vp); 1088 ufhp = (struct ufid *)fhp; 1089 ufhp->ufid_len = sizeof(struct ufid); 1090 ufhp->ufid_ino = ip->i_number; 1091 ufhp->ufid_gen = ip->i_gen; 1092 return (0); 1093} 1094 1095/* 1096 * Write a superblock and associated information back to disk. 1097 */ 1098static int 1099ext2_sbupdate(mp, waitfor) 1100 struct ext2mount *mp; 1101 int waitfor; 1102{ 1103 struct ext2_sb_info *fs = mp->um_e2fs; 1104 struct ext2_super_block *es = fs->s_es; 1105 struct buf *bp; 1106 int error = 0; 1107/* 1108printf("\nupdating superblock, waitfor=%s\n", waitfor == MNT_WAIT ? "yes":"no"); 1109*/ 1110 bp = getblk(mp->um_devvp, SBLOCK, SBSIZE, 0, 0, 0); 1111 bcopy((caddr_t)es, bp->b_data, (u_int)sizeof(struct ext2_super_block)); 1112 if (waitfor == MNT_WAIT) 1113 error = bwrite(bp); 1114 else 1115 bawrite(bp); 1116 1117 /* 1118 * The buffers for group descriptors, inode bitmaps and block bitmaps 1119 * are not busy at this point and are (hopefully) written by the 1120 * usual sync mechanism. No need to write them here 1121 */ 1122 1123 return (error); 1124} 1125 1126/* 1127 * Return the root of a filesystem. 1128 */ 1129static int 1130ext2_root(mp, flags, vpp, td) 1131 struct mount *mp; 1132 int flags; 1133 struct vnode **vpp; 1134 struct thread *td; 1135{ 1136 struct vnode *nvp; 1137 int error; 1138 1139 error = VFS_VGET(mp, (ino_t)ROOTINO, LK_EXCLUSIVE, &nvp); 1140 if (error) 1141 return (error); 1142 *vpp = nvp; 1143 return (0); 1144} 1145