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