59#include <sys/disklabel.h> 60#include <sys/ioctl.h> 61#include <sys/errno.h> 62#include <sys/malloc.h> 63#include <sys/stat.h> 64 65#include <miscfs/specfs/specdev.h> 66 67#include <ufs/ufs/quota.h> 68#include <ufs/ufs/ufsmount.h> 69#include <ufs/ufs/inode.h> 70#include <ufs/ufs/ufs_extern.h> 71 72#include <gnu/ext2fs/fs.h> 73#include <gnu/ext2fs/ext2_extern.h> 74#include <gnu/ext2fs/ext2_fs.h> 75#include <gnu/ext2fs/ext2_fs_sb.h> 76 77static int ext2_fhtovp __P((struct mount *, struct fid *, struct mbuf *, 78 struct vnode **, int *, struct ucred **)); 79static int ext2_flushfiles __P((struct mount *mp, int flags, struct proc *p)); 80static int ext2_mount __P((struct mount *, 81 char *, caddr_t, struct nameidata *, struct proc *)); 82static int ext2_mountfs __P((struct vnode *, struct mount *, struct proc *)); 83static int ext2_reload __P((struct mount *mountp, struct ucred *cred, 84 struct proc *p)); 85static int ext2_sbupdate __P((struct ufsmount *, int)); 86static int ext2_statfs __P((struct mount *, struct statfs *, struct proc *)); 87static int ext2_sync __P((struct mount *, int, struct ucred *, struct proc *)); 88static int ext2_unmount __P((struct mount *, int, struct proc *)); 89static int ext2_vget __P((struct mount *, ino_t, struct vnode **)); 90static int ext2_vptofh __P((struct vnode *, struct fid *)); 91 92static struct vfsops ext2fs_vfsops = { 93 ext2_mount, 94 ufs_start, /* empty function */ 95 ext2_unmount, 96 ufs_root, /* root inode via vget */ 97 ufs_quotactl, /* does operations associated with quotas */ 98 ext2_statfs, 99 ext2_sync, 100 ext2_vget, 101 ext2_fhtovp, 102 ext2_vptofh, 103 ext2_init, 104}; 105 106#if defined(__FreeBSD__) 107VFS_SET(ext2fs_vfsops, ext2fs, MOUNT_EXT2FS, 0); 108#define bsd_malloc malloc 109#define bsd_free free 110#endif 111 112extern u_long nextgennumber; 113#ifdef __FreeBSD__ 114static int ext2fs_inode_hash_lock; 115#endif 116 117static int compute_sb_data __P((struct vnode * devvp, 118 struct ext2_super_block * es, 119 struct ext2_sb_info * fs)); 120 121#ifdef notyet 122static int ext2_mountroot __P((void)); 123 124/* 125 * Called by main() when ext2fs is going to be mounted as root. 126 * 127 * Name is updated by mount(8) after booting. 128 */ 129#define ROOTNAME "root_device" 130 131static int 132ext2_mountroot() 133{ 134#if !defined(__FreeBSD__) 135 extern struct vnode *rootvp; 136#endif 137 register struct ext2_sb_info *fs; 138 register struct mount *mp; 139#if defined(__FreeBSD__) 140 struct proc *p = curproc; 141#else 142 struct proc *p = get_proc(); /* XXX */ 143#endif 144 struct ufsmount *ump; 145 u_int size; 146 int error; 147 148 /* 149 * Get vnodes for swapdev and rootdev. 150 */ 151 if (bdevvp(swapdev, &swapdev_vp) || bdevvp(rootdev, &rootvp)) 152 panic("ext2_mountroot: can't setup bdevvp's"); 153 154 mp = bsd_malloc((u_long)sizeof(struct mount), M_MOUNT, M_WAITOK); 155 bzero((char *)mp, (u_long)sizeof(struct mount)); 156 mp->mnt_op = &ext2fs_vfsops; 157 mp->mnt_flag = MNT_RDONLY; 158 if (error = ext2_mountfs(rootvp, mp, p)) { 159 bsd_free(mp, M_MOUNT); 160 return (error); 161 } 162 if (error = vfs_lock(mp)) { 163 (void)ext2_unmount(mp, 0, p); 164 bsd_free(mp, M_MOUNT); 165 return (error); 166 } 167#if defined(__FreeBSD__) 168 CIRCLEQ_INSERT_TAIL(&mountlist, mp, mnt_list); 169#else 170 TAILQ_INSERT_TAIL(&mountlist, mp, mnt_list); 171#endif 172 mp->mnt_flag |= MNT_ROOTFS; 173 mp->mnt_vnodecovered = NULLVP; 174 ump = VFSTOUFS(mp); 175 fs = ump->um_e2fs; 176 bzero(fs->fs_fsmnt, sizeof(fs->fs_fsmnt)); 177 fs->fs_fsmnt[0] = '/'; 178 bcopy((caddr_t)fs->fs_fsmnt, (caddr_t)mp->mnt_stat.f_mntonname, 179 MNAMELEN); 180 (void) copystr(ROOTNAME, mp->mnt_stat.f_mntfromname, MNAMELEN - 1, 181 &size); 182 bzero(mp->mnt_stat.f_mntfromname + size, MNAMELEN - size); 183 (void)ext2_statfs(mp, &mp->mnt_stat, p); 184 vfs_unlock(mp); 185 inittodr(fs->s_es->s_wtime); /* this helps to set the time */ 186 return (0); 187} 188#endif 189 190/* 191 * VFS Operations. 192 * 193 * mount system call 194 */ 195static int 196ext2_mount(mp, path, data, ndp, p) 197 register struct mount *mp; 198 char *path; 199 caddr_t data; /* this is actually a (struct ufs_args *) */ 200 struct nameidata *ndp; 201 struct proc *p; 202{ 203 struct vnode *devvp; 204 struct ufs_args args; 205 struct ufsmount *ump = 0; 206 register struct ext2_sb_info *fs; 207 u_int size; 208 int error, flags; 209 210 if (error = copyin(data, (caddr_t)&args, sizeof (struct ufs_args))) 211 return (error); 212 /* 213 * If updating, check whether changing from read-only to 214 * read/write; if there is no device name, that's all we do. 215 */ 216 if (mp->mnt_flag & MNT_UPDATE) { 217 ump = VFSTOUFS(mp); 218 fs = ump->um_e2fs; 219 error = 0; 220 if (fs->s_rd_only == 0 && (mp->mnt_flag & MNT_RDONLY)) { 221 flags = WRITECLOSE; 222 if (mp->mnt_flag & MNT_FORCE) 223 flags |= FORCECLOSE; 224 if (vfs_busy(mp, LK_NOWAIT, 0, p)) 225 return (EBUSY); 226 error = ext2_flushfiles(mp, flags, p); 227 vfs_unbusy(mp, p); 228 } 229 if (!error && (mp->mnt_flag & MNT_RELOAD)) 230 error = ext2_reload(mp, ndp->ni_cnd.cn_cred, p); 231 if (error) 232 return (error); 233 if (fs->s_rd_only && (mp->mnt_flag & MNT_WANTRDWR)) 234 fs->s_rd_only = 0; 235 if (fs->s_rd_only == 0) { 236 /* don't say it's clean */ 237 fs->s_es->s_state &= ~EXT2_VALID_FS; 238 ext2_sbupdate(ump, MNT_WAIT); 239 } 240 if (args.fspec == 0) { 241 /* 242 * Process export requests. 243 */ 244 return (vfs_export(mp, &ump->um_export, &args.export)); 245 } 246 } 247 /* 248 * Not an update, or updating the name: look up the name 249 * and verify that it refers to a sensible block device. 250 */ 251 NDINIT(ndp, LOOKUP, FOLLOW, UIO_USERSPACE, args.fspec, p); 252 if (error = namei(ndp)) 253 return (error); 254 devvp = ndp->ni_vp; 255 256 if (devvp->v_type != VBLK) { 257 vrele(devvp); 258 return (ENOTBLK); 259 } 260 if (major(devvp->v_rdev) >= nblkdev) { 261 vrele(devvp); 262 return (ENXIO); 263 } 264 if ((mp->mnt_flag & MNT_UPDATE) == 0) 265 error = ext2_mountfs(devvp, mp, p); 266 else { 267 if (devvp != ump->um_devvp) 268 error = EINVAL; /* needs translation */ 269 else 270 vrele(devvp); 271 } 272 if (error) { 273 vrele(devvp); 274 return (error); 275 } 276 ump = VFSTOUFS(mp); 277 fs = ump->um_e2fs; 278 (void) copyinstr(path, fs->fs_fsmnt, sizeof(fs->fs_fsmnt) - 1, &size); 279 bzero(fs->fs_fsmnt + size, sizeof(fs->fs_fsmnt) - size); 280 bcopy((caddr_t)fs->fs_fsmnt, (caddr_t)mp->mnt_stat.f_mntonname, 281 MNAMELEN); 282 (void) copyinstr(args.fspec, mp->mnt_stat.f_mntfromname, MNAMELEN - 1, 283 &size); 284 bzero(mp->mnt_stat.f_mntfromname + size, MNAMELEN - size); 285 (void)ext2_statfs(mp, &mp->mnt_stat, p); 286 return (0); 287} 288 289/* 290 * checks that the data in the descriptor blocks make sense 291 * this is taken from ext2/super.c 292 */ 293static int ext2_check_descriptors (struct ext2_sb_info * sb) 294{ 295 int i; 296 int desc_block = 0; 297 unsigned long block = sb->s_es->s_first_data_block; 298 struct ext2_group_desc * gdp = NULL; 299 300 /* ext2_debug ("Checking group descriptors"); */ 301 302 for (i = 0; i < sb->s_groups_count; i++) 303 { 304 /* examine next descriptor block */ 305 if ((i % EXT2_DESC_PER_BLOCK(sb)) == 0) 306 gdp = (struct ext2_group_desc *) 307 sb->s_group_desc[desc_block++]->b_data; 308 if (gdp->bg_block_bitmap < block || 309 gdp->bg_block_bitmap >= block + EXT2_BLOCKS_PER_GROUP(sb)) 310 { 311 printf ("ext2_check_descriptors: " 312 "Block bitmap for group %d" 313 " not in group (block %lu)!", 314 i, (unsigned long) gdp->bg_block_bitmap); 315 return 0; 316 } 317 if (gdp->bg_inode_bitmap < block || 318 gdp->bg_inode_bitmap >= block + EXT2_BLOCKS_PER_GROUP(sb)) 319 { 320 printf ("ext2_check_descriptors: " 321 "Inode bitmap for group %d" 322 " not in group (block %lu)!", 323 i, (unsigned long) gdp->bg_inode_bitmap); 324 return 0; 325 } 326 if (gdp->bg_inode_table < block || 327 gdp->bg_inode_table + sb->s_itb_per_group >= 328 block + EXT2_BLOCKS_PER_GROUP(sb)) 329 { 330 printf ("ext2_check_descriptors: " 331 "Inode table for group %d" 332 " not in group (block %lu)!", 333 i, (unsigned long) gdp->bg_inode_table); 334 return 0; 335 } 336 block += EXT2_BLOCKS_PER_GROUP(sb); 337 gdp++; 338 } 339 return 1; 340} 341 342/* 343 * this computes the fields of the ext2_sb_info structure from the 344 * data in the ext2_super_block structure read in 345 */ 346static int compute_sb_data(devvp, es, fs) 347 struct vnode * devvp; 348 struct ext2_super_block * es; 349 struct ext2_sb_info * fs; 350{ 351 int db_count, error; 352 int i, j; 353 int logic_sb_block = 1; /* XXX for now */ 354 355#if 1 356#define V(v) 357#else 358#define V(v) printf(#v"= %d\n", fs->v); 359#endif 360 361 fs->s_blocksize = EXT2_MIN_BLOCK_SIZE << es->s_log_block_size; 362 V(s_blocksize) 363 fs->s_bshift = EXT2_MIN_BLOCK_LOG_SIZE + es->s_log_block_size; 364 V(s_bshift) 365 fs->s_fsbtodb = es->s_log_block_size + 1; 366 V(s_fsbtodb) 367 fs->s_qbmask = fs->s_blocksize - 1; 368 V(s_bmask) 369 fs->s_blocksize_bits = EXT2_BLOCK_SIZE_BITS(es); 370 V(s_blocksize_bits) 371 fs->s_frag_size = EXT2_MIN_FRAG_SIZE << es->s_log_frag_size; 372 V(s_frag_size) 373 if (fs->s_frag_size) 374 fs->s_frags_per_block = fs->s_blocksize / fs->s_frag_size; 375 V(s_frags_per_block) 376 fs->s_blocks_per_group = es->s_blocks_per_group; 377 V(s_blocks_per_group) 378 fs->s_frags_per_group = es->s_frags_per_group; 379 V(s_frags_per_group) 380 fs->s_inodes_per_group = es->s_inodes_per_group; 381 V(s_inodes_per_group) 382 fs->s_inodes_per_block = fs->s_blocksize / EXT2_INODE_SIZE; 383 V(s_inodes_per_block) 384 fs->s_itb_per_group = fs->s_inodes_per_group /fs->s_inodes_per_block; 385 V(s_itb_per_group) 386 fs->s_desc_per_block = fs->s_blocksize / sizeof (struct ext2_group_desc); 387 V(s_desc_per_block) 388 /* s_resuid / s_resgid ? */ 389 fs->s_groups_count = (es->s_blocks_count - 390 es->s_first_data_block + 391 EXT2_BLOCKS_PER_GROUP(fs) - 1) / 392 EXT2_BLOCKS_PER_GROUP(fs); 393 V(s_groups_count) 394 db_count = (fs->s_groups_count + EXT2_DESC_PER_BLOCK(fs) - 1) / 395 EXT2_DESC_PER_BLOCK(fs); 396 fs->s_db_per_group = db_count; 397 V(s_db_per_group) 398 399 fs->s_group_desc = bsd_malloc(db_count * sizeof (struct buf *), 400 M_UFSMNT, M_WAITOK); 401 402 /* adjust logic_sb_block */ 403 if(fs->s_blocksize > SBSIZE) 404 /* Godmar thinks: if the blocksize is greater than 1024, then 405 the superblock is logically part of block zero. 406 */ 407 logic_sb_block = 0; 408 409 for (i = 0; i < db_count; i++) { 410 error = bread(devvp , fsbtodb(fs, logic_sb_block + i + 1), 411 fs->s_blocksize, NOCRED, &fs->s_group_desc[i]); 412 if(error) { 413 for (j = 0; j < i; j++) 414 brelse(fs->s_group_desc[j]); 415 bsd_free(fs->s_group_desc, M_UFSMNT); 416 printf("EXT2-fs: unable to read group descriptors (%d)\n", error); 417 return EIO; 418 } 419 } 420 if(!ext2_check_descriptors(fs)) { 421 for (j = 0; j < db_count; j++) 422 brelse(fs->s_group_desc[j]); 423 bsd_free(fs->s_group_desc, M_UFSMNT); 424 printf("EXT2-fs: (ext2_check_descriptors failure) " 425 "unable to read group descriptors\n"); 426 return EIO; 427 } 428 429 for (i = 0; i < EXT2_MAX_GROUP_LOADED; i++) { 430 fs->s_inode_bitmap_number[i] = 0; 431 fs->s_inode_bitmap[i] = NULL; 432 fs->s_block_bitmap_number[i] = 0; 433 fs->s_block_bitmap[i] = NULL; 434 } 435 fs->s_loaded_inode_bitmaps = 0; 436 fs->s_loaded_block_bitmaps = 0; 437 return 0; 438} 439 440/* 441 * Reload all incore data for a filesystem (used after running fsck on 442 * the root filesystem and finding things to fix). The filesystem must 443 * be mounted read-only. 444 * 445 * Things to do to update the mount: 446 * 1) invalidate all cached meta-data. 447 * 2) re-read superblock from disk. 448 * 3) re-read summary information from disk. 449 * 4) invalidate all inactive vnodes. 450 * 5) invalidate all cached file data. 451 * 6) re-read inode data for all active vnodes. 452 */ 453static int 454ext2_reload(mountp, cred, p) 455 register struct mount *mountp; 456 struct ucred *cred; 457 struct proc *p; 458{ 459 register struct vnode *vp, *nvp, *devvp; 460 struct inode *ip; 461 struct buf *bp; 462 struct ext2_super_block * es; 463 struct ext2_sb_info *fs; 464 int error; 465 466 if ((mountp->mnt_flag & MNT_RDONLY) == 0) 467 return (EINVAL); 468 /* 469 * Step 1: invalidate all cached meta-data. 470 */ 471 devvp = VFSTOUFS(mountp)->um_devvp; 472 if (vinvalbuf(devvp, 0, cred, p, 0, 0)) 473 panic("ext2_reload: dirty1"); 474 /* 475 * Step 2: re-read superblock from disk. 476 * constants have been adjusted for ext2 477 */ 478 if (error = bread(devvp, SBLOCK, SBSIZE, NOCRED, &bp)) 479 return (error); 480 es = (struct ext2_super_block *)bp->b_data; 481 if (es->s_magic != EXT2_SUPER_MAGIC) { 482 if(es->s_magic == EXT2_PRE_02B_MAGIC) 483 printf("This filesystem bears the magic number of a pre " 484 "0.2b version of ext2. This is not supported by " 485 "Lites.\n"); 486 else 487 printf("Wrong magic number: %x (expected %x for ext2 fs\n", 488 es->s_magic, EXT2_SUPER_MAGIC); 489 brelse(bp); 490 return (EIO); /* XXX needs translation */ 491 } 492 fs = VFSTOUFS(mountp)->um_e2fs; 493 bcopy(bp->b_data, fs->s_es, sizeof(struct ext2_super_block)); 494 495 if(error = compute_sb_data(devvp, es, fs)) { 496 brelse(bp); 497 return error; 498 } 499#ifdef UNKLAR 500 if (fs->fs_sbsize < SBSIZE) 501 bp->b_flags |= B_INVAL; 502#endif 503 brelse(bp); 504 505loop: 506 for (vp = mountp->mnt_vnodelist.lh_first; vp != NULL; vp = nvp) { 507 nvp = vp->v_mntvnodes.le_next; 508 /* 509 * Step 4: invalidate all inactive vnodes. 510 */ 511 if (vp->v_usecount == 0) { 512 vgone(vp); 513 continue; 514 } 515 /* 516 * Step 5: invalidate all cached file data. 517 */ 518 if (vget(vp, LK_EXCLUSIVE, p)) 519 goto loop; 520 if (vinvalbuf(vp, 0, cred, p, 0, 0)) 521 panic("ext2_reload: dirty2"); 522 /* 523 * Step 6: re-read inode data for all active vnodes. 524 */ 525 ip = VTOI(vp); 526 if (error = 527 bread(devvp, fsbtodb(fs, ino_to_fsba(fs, ip->i_number)), 528 (int)fs->s_blocksize, NOCRED, &bp)) { 529 vput(vp); 530 return (error); 531 } 532 ext2_ei2di((struct ext2_inode *) ((char *)bp->b_data + 533 EXT2_INODE_SIZE * ino_to_fsbo(fs, ip->i_number)), 534 &ip->i_din); 535 brelse(bp); 536 vput(vp); 537 if (vp->v_mount != mountp) 538 goto loop; 539 } 540 return (0); 541} 542 543/* 544 * Common code for mount and mountroot 545 */ 546static int 547ext2_mountfs(devvp, mp, p) 548 register struct vnode *devvp; 549 struct mount *mp; 550 struct proc *p; 551{ 552 register struct ufsmount *ump; 553 struct buf *bp; 554 register struct ext2_sb_info *fs; 555 struct ext2_super_block * es; 556 dev_t dev = devvp->v_rdev; 557 struct partinfo dpart; 558 int havepart = 0; 559 int error, i, size; 560 int ronly; 561#if !defined(__FreeBSD__) 562 extern struct vnode *rootvp; 563#endif 564 565 /* 566 * Disallow multiple mounts of the same device. 567 * Disallow mounting of a device that is currently in use 568 * (except for root, which might share swap device for miniroot). 569 * Flush out any old buffers remaining from a previous use. 570 */ 571 if (error = vfs_mountedon(devvp)) 572 return (error); 573 if (vcount(devvp) > 1 && devvp != rootvp) 574 return (EBUSY); 575 if (error = vinvalbuf(devvp, V_SAVE, p->p_ucred, p, 0, 0)) 576 return (error); 577#ifdef READONLY 578/* turn on this to force it to be read-only */ 579 mp->mnt_flag |= MNT_RDONLY; 580#endif 581 582 ronly = (mp->mnt_flag & MNT_RDONLY) != 0; 583 if (error = VOP_OPEN(devvp, ronly ? FREAD : FREAD|FWRITE, FSCRED, p)) 584 return (error); 585 if (VOP_IOCTL(devvp, DIOCGPART, (caddr_t)&dpart, FREAD, NOCRED, p) != 0) 586 size = DEV_BSIZE; 587 else { 588 havepart = 1; 589 size = dpart.disklab->d_secsize; 590 } 591 592 bp = NULL; 593 ump = NULL; 594 if (error = bread(devvp, SBLOCK, SBSIZE, NOCRED, &bp)) 595 goto out; 596 es = (struct ext2_super_block *)bp->b_data; 597 if (es->s_magic != EXT2_SUPER_MAGIC) { 598 if(es->s_magic == EXT2_PRE_02B_MAGIC) 599 printf("This filesystem bears the magic number of a pre " 600 "0.2b version of ext2. This is not supported by " 601 "Lites.\n"); 602 else 603 printf("Wrong magic number: %x (expected %x for EXT2FS)\n", 604 es->s_magic, EXT2_SUPER_MAGIC); 605 error = EINVAL; /* XXX needs translation */ 606 goto out; 607 } 608 ump = bsd_malloc(sizeof *ump, M_UFSMNT, M_WAITOK); 609 bzero((caddr_t)ump, sizeof *ump); 610 /* I don't know whether this is the right strategy. Note that 611 we dynamically allocate both a ext2_sb_info and a ext2_super_block 612 while Linux keeps the super block in a locked buffer 613 */ 614 ump->um_e2fs = bsd_malloc(sizeof(struct ext2_sb_info), 615 M_UFSMNT, M_WAITOK); 616 ump->um_e2fs->s_es = bsd_malloc(sizeof(struct ext2_super_block), 617 M_UFSMNT, M_WAITOK); 618 bcopy(es, ump->um_e2fs->s_es, (u_int)sizeof(struct ext2_super_block)); 619 if(error = compute_sb_data(devvp, ump->um_e2fs->s_es, ump->um_e2fs)) { 620 brelse(bp); 621 return error; 622 } 623 brelse(bp); 624 bp = NULL; 625 fs = ump->um_e2fs; 626 fs->s_rd_only = ronly; /* ronly is set according to mnt_flags */ 627 if (!(fs->s_es->s_state & EXT2_VALID_FS)) { 628 printf("WARNING: %s was not properly dismounted\n", 629 fs->fs_fsmnt); 630 } 631 /* if the fs is not mounted read-only, make sure the super block is 632 always written back on a sync() 633 */ 634 if (ronly == 0) { 635 fs->s_dirt = 1; /* mark it modified */ 636 fs->s_es->s_state &= ~EXT2_VALID_FS; /* set fs invalid */ 637 } 638 mp->mnt_data = (qaddr_t)ump; 639 mp->mnt_stat.f_fsid.val[0] = (long)dev; 640 mp->mnt_stat.f_fsid.val[1] = MOUNT_EXT2FS; 641 mp->mnt_maxsymlinklen = EXT2_MAXSYMLINKLEN; 642 mp->mnt_flag |= MNT_LOCAL; 643 ump->um_mountp = mp; 644 ump->um_dev = dev; 645 ump->um_devvp = devvp; 646 /* setting those two parameters allows us to use 647 ufs_bmap w/o changse ! 648 */ 649 ump->um_nindir = EXT2_ADDR_PER_BLOCK(fs); 650 ump->um_bptrtodb = fs->s_es->s_log_block_size + 1; 651 ump->um_seqinc = EXT2_FRAGS_PER_BLOCK(fs); 652 for (i = 0; i < MAXQUOTAS; i++) 653 ump->um_quotas[i] = NULLVP; 654 devvp->v_specflags |= SI_MOUNTEDON; 655 if (ronly == 0) 656 ext2_sbupdate(ump, MNT_WAIT); 657 return (0); 658out: 659 if (bp) 660 brelse(bp); 661 (void)VOP_CLOSE(devvp, ronly ? FREAD : FREAD|FWRITE, NOCRED, p); 662 if (ump) { 663 bsd_free(ump->um_fs, M_UFSMNT); 664 bsd_free(ump, M_UFSMNT); 665 mp->mnt_data = (qaddr_t)0; 666 } 667 return (error); 668} 669 670/* 671 * unmount system call 672 */ 673static int 674ext2_unmount(mp, mntflags, p) 675 struct mount *mp; 676 int mntflags; 677 struct proc *p; 678{ 679 register struct ufsmount *ump; 680 register struct ext2_sb_info *fs; 681 int error, flags, ronly, i; 682 683 flags = 0; 684 if (mntflags & MNT_FORCE) { 685 if (mp->mnt_flag & MNT_ROOTFS) 686 return (EINVAL); 687 flags |= FORCECLOSE; 688 } 689 if (error = ext2_flushfiles(mp, flags, p)) 690 return (error); 691 ump = VFSTOUFS(mp); 692 fs = ump->um_e2fs; 693 ronly = fs->s_rd_only; 694 if (!ronly) { 695 fs->s_es->s_state |= EXT2_VALID_FS; /* was fs_clean = 1 */ 696 ext2_sbupdate(ump, MNT_WAIT); 697 } 698 /* release buffers containing group descriptors */ 699 for(i = 0; i < fs->s_db_per_group; i++) 700 brelse(fs->s_group_desc[i]); 701 /* release cached inode/block bitmaps */ 702 for (i = 0; i < EXT2_MAX_GROUP_LOADED; i++) 703 if (fs->s_inode_bitmap[i]) 704 brelse (fs->s_inode_bitmap[i]); 705 for (i = 0; i < EXT2_MAX_GROUP_LOADED; i++) 706 if (fs->s_block_bitmap[i]) 707 brelse (fs->s_block_bitmap[i]); 708 709 ump->um_devvp->v_specflags &= ~SI_MOUNTEDON; 710 error = VOP_CLOSE(ump->um_devvp, ronly ? FREAD : FREAD|FWRITE, 711 NOCRED, p); 712 vrele(ump->um_devvp); 713 bsd_free(fs->s_es, M_UFSMNT); 714 bsd_free(fs, M_UFSMNT); 715 bsd_free(ump, M_UFSMNT); 716 mp->mnt_data = (qaddr_t)0; 717 mp->mnt_flag &= ~MNT_LOCAL; 718 return (error); 719} 720 721/* 722 * Flush out all the files in a filesystem. 723 */ 724static int 725ext2_flushfiles(mp, flags, p) 726 register struct mount *mp; 727 int flags; 728 struct proc *p; 729{ 730 register struct ufsmount *ump; 731 int error; 732#if QUOTA 733 int i; 734#endif 735 736 ump = VFSTOUFS(mp); 737#if QUOTA 738 if (mp->mnt_flag & MNT_QUOTA) { 739 if (error = vflush(mp, NULLVP, SKIPSYSTEM|flags)) 740 return (error); 741 for (i = 0; i < MAXQUOTAS; i++) { 742 if (ump->um_quotas[i] == NULLVP) 743 continue; 744 quotaoff(p, mp, i); 745 } 746 /* 747 * Here we fall through to vflush again to ensure 748 * that we have gotten rid of all the system vnodes. 749 */ 750 } 751#endif 752 error = vflush(mp, NULLVP, flags); 753 return (error); 754} 755 756/* 757 * Get file system statistics. 758 * taken from ext2/super.c ext2_statfs 759 */ 760static int 761ext2_statfs(mp, sbp, p) 762 struct mount *mp; 763 register struct statfs *sbp; 764 struct proc *p; 765{ 766 unsigned long overhead; 767 unsigned long overhead_per_group; 768 769 register struct ufsmount *ump; 770 register struct ext2_sb_info *fs; 771 register struct ext2_super_block *es; 772 773 ump = VFSTOUFS(mp); 774 fs = ump->um_e2fs; 775 es = fs->s_es; 776 777 if (es->s_magic != EXT2_SUPER_MAGIC) 778 panic("ext2_statfs - magic number spoiled"); 779 780 /* 781 * Compute the overhead (FS structures) 782 */ 783 overhead_per_group = 1 /* super block */ + 784 fs->s_db_per_group + 785 1 /* block bitmap */ + 786 1 /* inode bitmap */ + 787 fs->s_itb_per_group; 788 overhead = es->s_first_data_block + 789 fs->s_groups_count * overhead_per_group; 790 791 sbp->f_type = MOUNT_EXT2FS; 792 sbp->f_bsize = EXT2_FRAG_SIZE(fs); 793 sbp->f_iosize = EXT2_BLOCK_SIZE(fs); 794 sbp->f_blocks = es->s_blocks_count - overhead; 795 sbp->f_bfree = es->s_free_blocks_count; 796 sbp->f_bavail = sbp->f_bfree - es->s_r_blocks_count; 797 sbp->f_files = es->s_inodes_count; 798 sbp->f_ffree = es->s_free_inodes_count; 799 if (sbp != &mp->mnt_stat) { 800 bcopy((caddr_t)mp->mnt_stat.f_mntonname, 801 (caddr_t)&sbp->f_mntonname[0], MNAMELEN); 802 bcopy((caddr_t)mp->mnt_stat.f_mntfromname, 803 (caddr_t)&sbp->f_mntfromname[0], MNAMELEN); 804 } 805 return (0); 806} 807 808/* 809 * Go through the disk queues to initiate sandbagged IO; 810 * go through the inodes to write those that have been modified; 811 * initiate the writing of the super block if it has been modified. 812 * 813 * Note: we are always called with the filesystem marked `MPBUSY'. 814 */ 815static int 816ext2_sync(mp, waitfor, cred, p) 817 struct mount *mp; 818 int waitfor; 819 struct ucred *cred; 820 struct proc *p; 821{ 822 register struct vnode *vp; 823 register struct inode *ip; 824 register struct ufsmount *ump = VFSTOUFS(mp); 825 register struct ext2_sb_info *fs; 826 int error, allerror = 0; 827 828 fs = ump->um_e2fs; 829 /* 830 * Write back modified superblock. 831 * Consistency check that the superblock 832 * is still in the buffer cache. 833 */ 834 if (fs->s_dirt) { 835#if !defined(__FreeBSD__) 836 struct timeval time; 837#endif 838 839 if (fs->s_rd_only != 0) { /* XXX */ 840 printf("fs = %s\n", fs->fs_fsmnt); 841 panic("update: rofs mod"); 842 } 843 fs->s_dirt = 0; 844#if !defined(__FreeBSD__) 845 get_time(&time); 846#endif 847 fs->s_es->s_wtime = time.tv_sec; 848 allerror = ext2_sbupdate(ump, waitfor); 849 } 850 /* 851 * Write back each (modified) inode. 852 */ 853loop: 854 for (vp = mp->mnt_vnodelist.lh_first; 855 vp != NULL; 856 vp = vp->v_mntvnodes.le_next) { 857 /* 858 * If the vnode that we are about to sync is no longer 859 * associated with this mount point, start over. 860 */ 861 if (vp->v_mount != mp) 862 goto loop; 863 if (VOP_ISLOCKED(vp)) 864 continue; 865 ip = VTOI(vp); 866 if ((ip->i_flag & 867 (IN_ACCESS | IN_CHANGE | IN_MODIFIED | IN_UPDATE)) == 0 && 868 vp->v_dirtyblkhd.lh_first == NULL) 869 continue; 870 if (vget(vp, LK_EXCLUSIVE, p)) 871 goto loop; 872 if (error = VOP_FSYNC(vp, cred, waitfor, p)) 873 allerror = error; 874 vput(vp); 875 } 876 /* 877 * Force stale file system control information to be flushed. 878 */ 879 if (error = VOP_FSYNC(ump->um_devvp, cred, waitfor, p)) 880 allerror = error; 881#if QUOTA 882 qsync(mp); 883#endif 884 return (allerror); 885} 886 887/* 888 * Look up a EXT2FS dinode number to find its incore vnode, otherwise read it 889 * in from disk. If it is in core, wait for the lock bit to clear, then 890 * return the inode locked. Detection and handling of mount points must be 891 * done by the calling routine. 892 */ 893static int 894ext2_vget(mp, ino, vpp) 895 struct mount *mp; 896 ino_t ino; 897 struct vnode **vpp; 898{ 899 register struct ext2_sb_info *fs; 900 register struct inode *ip; 901 struct ufsmount *ump; 902 struct buf *bp; 903 struct vnode *vp; 904 dev_t dev; 905 int i, type, error; 906 int used_blocks; 907 908 ump = VFSTOUFS(mp); 909 dev = ump->um_dev; 910restart: 911 if ((*vpp = ufs_ihashget(dev, ino)) != NULL) 912 return (0); 913 914#ifdef __FreeBSD__ 915 /* 916 * Lock out the creation of new entries in the FFS hash table in 917 * case getnewvnode() or MALLOC() blocks, otherwise a duplicate 918 * may occur! 919 */ 920 if (ext2fs_inode_hash_lock) { 921 while (ext2fs_inode_hash_lock) { 922 ext2fs_inode_hash_lock = -1; 923 tsleep(&ext2fs_inode_hash_lock, PVM, "ffsvgt", 0); 924 } 925 goto restart; 926 } 927 ext2fs_inode_hash_lock = 1; 928#endif 929 930 /* Allocate a new vnode/inode. */ 931 if (error = getnewvnode(VT_UFS, mp, ext2_vnodeop_p, &vp)) { 932 *vpp = NULL; 933 return (error); 934 } 935 /* I don't really know what this 'type' does. I suppose it's some kind 936 * of memory accounting. Let's just book this memory on FFS's account 937 * If I'm not mistaken, this stuff isn't implemented anyway in Lites 938 */ 939 type = ump->um_devvp->v_tag == VT_MFS ? M_MFSNODE : M_FFSNODE; /* XXX */ 940 MALLOC(ip, struct inode *, sizeof(struct inode), type, M_WAITOK); 941#ifndef __FreeBSD__ 942 insmntque(vp, mp); 943#endif 944 bzero((caddr_t)ip, sizeof(struct inode)); 945 vp->v_data = ip; 946 ip->i_vnode = vp; 947 ip->i_e2fs = fs = ump->um_e2fs; 948 ip->i_dev = dev; 949 ip->i_number = ino; 950#if QUOTA 951 for (i = 0; i < MAXQUOTAS; i++) 952 ip->i_dquot[i] = NODQUOT; 953#endif 954 /* 955 * Put it onto its hash chain and lock it so that other requests for 956 * this inode will block if they arrive while we are sleeping waiting 957 * for old data structures to be purged or for the contents of the 958 * disk portion of this inode to be read. 959 */ 960 ufs_ihashins(ip); 961 962#ifdef __FreeBSD__ 963 if (ext2fs_inode_hash_lock < 0) 964 wakeup(&ext2fs_inode_hash_lock); 965 ext2fs_inode_hash_lock = 0; 966#endif 967 968 /* Read in the disk contents for the inode, copy into the inode. */ 969 /* Read in the disk contents for the inode, copy into the inode. */ 970#if 0 971printf("ext2_vget(%d) dbn= %d ", ino, fsbtodb(fs, ino_to_fsba(fs, ino))); 972#endif 973 if (error = bread(ump->um_devvp, fsbtodb(fs, ino_to_fsba(fs, ino)), 974 (int)fs->s_blocksize, NOCRED, &bp)) { 975 /* 976 * The inode does not contain anything useful, so it would 977 * be misleading to leave it on its hash chain. With mode 978 * still zero, it will be unlinked and returned to the free 979 * list by vput(). 980 */ 981 vput(vp); 982 brelse(bp); 983 *vpp = NULL; 984 return (error); 985 } 986 /* convert ext2 inode to dinode */ 987 ext2_ei2di((struct ext2_inode *) ((char *)bp->b_data + EXT2_INODE_SIZE * 988 ino_to_fsbo(fs, ino)), &ip->i_din); 989 ip->i_block_group = ino_to_cg(fs, ino); 990 ip->i_next_alloc_block = 0; 991 ip->i_next_alloc_goal = 0; 992 ip->i_prealloc_count = 0; 993 ip->i_prealloc_block = 0; 994 /* now we want to make sure that block pointers for unused 995 blocks are zeroed out - ext2_balloc depends on this 996 although for regular files and directories only 997 */ 998 if(S_ISDIR(ip->i_mode) || S_ISREG(ip->i_mode)) { 999 used_blocks = (ip->i_size+fs->s_blocksize-1) / fs->s_blocksize; 1000 for(i = used_blocks; i < EXT2_NDIR_BLOCKS; i++) 1001 ip->i_db[i] = 0; 1002 } 1003/* 1004 ext2_print_inode(ip); 1005*/ 1006 brelse(bp); 1007 1008 /* 1009 * Initialize the vnode from the inode, check for aliases. 1010 * Note that the underlying vnode may have changed. 1011 */ 1012 if (error = ufs_vinit(mp, ext2_specop_p, ext2_fifoop_p, &vp)) { 1013 vput(vp); 1014 *vpp = NULL; 1015 return (error); 1016 } 1017 /* 1018 * Finish inode initialization now that aliasing has been resolved. 1019 */ 1020 ip->i_devvp = ump->um_devvp; 1021 VREF(ip->i_devvp); 1022 /* 1023 * Set up a generation number for this inode if it does not 1024 * already have one. This should only happen on old filesystems. 1025 */ 1026 if (ip->i_gen == 0) { 1027#if !defined(__FreeBSD__) 1028 struct timeval time; 1029 get_time(&time); 1030#endif 1031 if (++nextgennumber < (u_long)time.tv_sec) 1032 nextgennumber = time.tv_sec; 1033 ip->i_gen = nextgennumber; 1034 if ((vp->v_mount->mnt_flag & MNT_RDONLY) == 0) 1035 ip->i_flag |= IN_MODIFIED; 1036 } 1037 *vpp = vp; 1038 return (0); 1039} 1040 1041/* 1042 * File handle to vnode 1043 * 1044 * Have to be really careful about stale file handles: 1045 * - check that the inode number is valid 1046 * - call ext2_vget() to get the locked inode 1047 * - check for an unallocated inode (i_mode == 0) 1048 * - check that the given client host has export rights and return 1049 * those rights via. exflagsp and credanonp 1050 */ 1051static int 1052ext2_fhtovp(mp, fhp, nam, vpp, exflagsp, credanonp) 1053 register struct mount *mp; 1054 struct fid *fhp; 1055 struct mbuf *nam; 1056 struct vnode **vpp; 1057 int *exflagsp; 1058 struct ucred **credanonp; 1059{ 1060 register struct ufid *ufhp; 1061 struct ext2_sb_info *fs; 1062 1063 ufhp = (struct ufid *)fhp; 1064 fs = VFSTOUFS(mp)->um_e2fs; 1065 if (ufhp->ufid_ino < ROOTINO || 1066 ufhp->ufid_ino >= fs->s_groups_count * fs->s_es->s_inodes_per_group) 1067 return (ESTALE); 1068 return (ufs_check_export(mp, ufhp, nam, vpp, exflagsp, credanonp)); 1069} 1070 1071/* 1072 * Vnode pointer to File handle 1073 */ 1074/* ARGSUSED */ 1075static int 1076ext2_vptofh(vp, fhp) 1077 struct vnode *vp; 1078 struct fid *fhp; 1079{ 1080 register struct inode *ip; 1081 register struct ufid *ufhp; 1082 1083 ip = VTOI(vp); 1084 ufhp = (struct ufid *)fhp; 1085 ufhp->ufid_len = sizeof(struct ufid); 1086 ufhp->ufid_ino = ip->i_number; 1087 ufhp->ufid_gen = ip->i_gen; 1088 return (0); 1089} 1090 1091/* 1092 * Write a superblock and associated information back to disk. 1093 */ 1094static int 1095ext2_sbupdate(mp, waitfor) 1096 struct ufsmount *mp; 1097 int waitfor; 1098{ 1099 register struct ext2_sb_info *fs = mp->um_e2fs; 1100 register struct ext2_super_block *es = fs->s_es; 1101 register struct buf *bp; 1102 int i, error = 0; 1103/* 1104printf("\nupdating superblock, waitfor=%s\n", waitfor == MNT_WAIT ? "yes":"no"); 1105*/ 1106 bp = getblk(mp->um_devvp, SBLOCK, SBSIZE, 0, 0); 1107 bcopy((caddr_t)es, bp->b_data, (u_int)sizeof(struct ext2_super_block)); 1108 if (waitfor == MNT_WAIT) 1109 error = bwrite(bp); 1110 else 1111 bawrite(bp); 1112 1113 /* write group descriptors back on disk */ 1114 for(i = 0; i < fs->s_db_per_group; i++) 1115 /* Godmar thinks: we must avoid using any of the b*write 1116 * functions here: we want to keep the buffer locked 1117 * so we use my 'housemade' write routine: 1118 */ 1119 error |= ll_w_block(fs->s_group_desc[i], waitfor == MNT_WAIT); 1120 1121 for (i = 0; i < EXT2_MAX_GROUP_LOADED; i++) 1122 if (fs->s_inode_bitmap[i]) 1123 ll_w_block (fs->s_inode_bitmap[i], 1); 1124 for (i = 0; i < EXT2_MAX_GROUP_LOADED; i++) 1125 if (fs->s_block_bitmap[i]) 1126 ll_w_block (fs->s_block_bitmap[i], 1); 1127 1128 return (error); 1129}
|