1 /* $OpenBSD: ext2fs_vfsops.c,v 1.53 2009/07/09 22:29:56 thib Exp $ */ 2 /* $NetBSD: ext2fs_vfsops.c,v 1.1 1997/06/11 09:34:07 bouyer Exp $ */ 3 4 /* 5 * Copyright (c) 1997 Manuel Bouyer. 6 * Copyright (c) 1989, 1991, 1993, 1994 7 * The Regents of the University of California. All rights reserved. 8 * 9 * Redistribution and use in source and binary forms, with or without 10 * modification, are permitted provided that the following conditions 11 * are met: 12 * 1. Redistributions of source code must retain the above copyright 13 * notice, this list of conditions and the following disclaimer. 14 * 2. Redistributions in binary form must reproduce the above copyright 15 * notice, this list of conditions and the following disclaimer in the 16 * documentation and/or other materials provided with the distribution. 17 * 3. Neither the name of the University nor the names of its contributors 18 * may be used to endorse or promote products derived from this software 19 * without specific prior written permission. 20 * 21 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 22 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 24 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 25 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 26 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 27 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 31 * SUCH DAMAGE. 32 * 33 * @(#)ffs_vfsops.c 8.14 (Berkeley) 11/28/94 34 * Modified for ext2fs by Manuel Bouyer. 35 */ 36 37 #include <sys/param.h> 38 #include <sys/systm.h> 39 #include <sys/namei.h> 40 #include <sys/proc.h> 41 #include <sys/kernel.h> 42 #include <sys/vnode.h> 43 #include <sys/socket.h> 44 #include <sys/mount.h> 45 #include <sys/buf.h> 46 #include <sys/device.h> 47 #include <sys/mbuf.h> 48 #include <sys/file.h> 49 #include <sys/disklabel.h> 50 #include <sys/ioctl.h> 51 #include <sys/errno.h> 52 #include <sys/malloc.h> 53 #include <sys/pool.h> 54 #include <sys/lock.h> 55 56 #include <miscfs/specfs/specdev.h> 57 58 #include <ufs/ufs/quota.h> 59 #include <ufs/ufs/ufsmount.h> 60 #include <ufs/ufs/inode.h> 61 #include <ufs/ufs/dir.h> 62 #include <ufs/ufs/ufs_extern.h> 63 64 #include <ufs/ext2fs/ext2fs.h> 65 #include <ufs/ext2fs/ext2fs_extern.h> 66 67 extern struct lock ufs_hashlock; 68 69 int ext2fs_sbupdate(struct ufsmount *, int); 70 static int ext2fs_checksb(struct ext2fs *, int); 71 72 extern struct vnodeopv_desc ext2fs_vnodeop_opv_desc; 73 extern struct vnodeopv_desc ext2fs_specop_opv_desc; 74 #ifdef FIFO 75 extern struct vnodeopv_desc ext2fs_fifoop_opv_desc; 76 #endif 77 78 struct vnodeopv_desc *ext2fs_vnodeopv_descs[] = { 79 &ext2fs_vnodeop_opv_desc, 80 &ext2fs_specop_opv_desc, 81 #ifdef FIFO 82 &ext2fs_fifoop_opv_desc, 83 #endif 84 NULL, 85 }; 86 87 const struct vfsops ext2fs_vfsops = { 88 ext2fs_mount, 89 ufs_start, 90 ext2fs_unmount, 91 ufs_root, 92 ufs_quotactl, 93 ext2fs_statfs, 94 ext2fs_sync, 95 ext2fs_vget, 96 ext2fs_fhtovp, 97 ext2fs_vptofh, 98 ext2fs_init, 99 ext2fs_sysctl, 100 ufs_check_export 101 }; 102 103 struct pool ext2fs_inode_pool; 104 struct pool ext2fs_dinode_pool; 105 106 extern u_long ext2gennumber; 107 108 int 109 ext2fs_init(struct vfsconf *vfsp) 110 { 111 pool_init(&ext2fs_inode_pool, sizeof(struct inode), 0, 0, 0, 112 "ext2inopl", &pool_allocator_nointr); 113 pool_init(&ext2fs_dinode_pool, sizeof(struct ext2fs_dinode), 0, 0, 0, 114 "ext2dinopl", &pool_allocator_nointr); 115 116 return (ufs_init(vfsp)); 117 } 118 119 /* 120 * Called by main() when ext2fs is going to be mounted as root. 121 * 122 * Name is updated by mount(8) after booting. 123 */ 124 #define ROOTNAME "root_device" 125 126 int 127 ext2fs_mountroot(void) 128 { 129 struct m_ext2fs *fs; 130 struct mount *mp; 131 struct proc *p = curproc; /* XXX */ 132 struct ufsmount *ump; 133 int error; 134 135 /* 136 * Get vnodes for swapdev and rootdev. 137 */ 138 if (bdevvp(swapdev, &swapdev_vp) || bdevvp(rootdev, &rootvp)) 139 panic("ext2fs_mountroot: can't setup bdevvp's"); 140 141 if ((error = vfs_rootmountalloc("ext2fs", "root_device", &mp)) != 0) { 142 vrele(rootvp); 143 return (error); 144 } 145 146 if ((error = ext2fs_mountfs(rootvp, mp, p)) != 0) { 147 mp->mnt_vfc->vfc_refcount--; 148 vfs_unbusy(mp); 149 free(mp, M_MOUNT); 150 vrele(rootvp); 151 return (error); 152 } 153 154 CIRCLEQ_INSERT_TAIL(&mountlist, mp, mnt_list); 155 ump = VFSTOUFS(mp); 156 fs = ump->um_e2fs; 157 bzero(fs->e2fs_fsmnt, sizeof(fs->e2fs_fsmnt)); 158 (void)copystr(mp->mnt_stat.f_mntonname, fs->e2fs_fsmnt, 159 sizeof(fs->e2fs_fsmnt) - 1, 0); 160 if (fs->e2fs.e2fs_rev > E2FS_REV0) { 161 bzero(fs->e2fs.e2fs_fsmnt, sizeof(fs->e2fs.e2fs_fsmnt)); 162 (void)copystr(mp->mnt_stat.f_mntonname, fs->e2fs.e2fs_fsmnt, 163 sizeof(fs->e2fs.e2fs_fsmnt) - 1, 0); 164 } 165 (void)ext2fs_statfs(mp, &mp->mnt_stat, p); 166 vfs_unbusy(mp); 167 inittodr(fs->e2fs.e2fs_wtime); 168 return (0); 169 } 170 171 /* 172 * VFS Operations. 173 * 174 * mount system call 175 */ 176 int 177 ext2fs_mount(struct mount *mp, const char *path, void *data, 178 struct nameidata *ndp, struct proc *p) 179 { 180 struct vnode *devvp; 181 struct ufs_args args; 182 struct ufsmount *ump = NULL; 183 struct m_ext2fs *fs; 184 size_t size; 185 int error, flags; 186 mode_t accessmode; 187 188 error = copyin(data, (caddr_t)&args, sizeof (struct ufs_args)); 189 if (error) 190 return (error); 191 /* 192 * If updating, check whether changing from read-only to 193 * read/write; if there is no device name, that's all we do. 194 */ 195 if (mp->mnt_flag & MNT_UPDATE) { 196 ump = VFSTOUFS(mp); 197 fs = ump->um_e2fs; 198 if (fs->e2fs_ronly == 0 && (mp->mnt_flag & MNT_RDONLY)) { 199 flags = WRITECLOSE; 200 if (mp->mnt_flag & MNT_FORCE) 201 flags |= FORCECLOSE; 202 error = ext2fs_flushfiles(mp, flags, p); 203 if (error == 0 && 204 ext2fs_cgupdate(ump, MNT_WAIT) == 0 && 205 (fs->e2fs.e2fs_state & E2FS_ERRORS) == 0) { 206 fs->e2fs.e2fs_state = E2FS_ISCLEAN; 207 (void)ext2fs_sbupdate(ump, MNT_WAIT); 208 } 209 if (error) 210 return (error); 211 fs->e2fs_ronly = 1; 212 } 213 if (mp->mnt_flag & MNT_RELOAD) { 214 error = ext2fs_reload(mp, ndp->ni_cnd.cn_cred, p); 215 if (error) 216 return (error); 217 } 218 if (fs->e2fs_ronly && (mp->mnt_flag & MNT_WANTRDWR)) { 219 /* 220 * If upgrade to read-write by non-root, then verify 221 * that user has necessary permissions on the device. 222 */ 223 if (p->p_ucred->cr_uid != 0) { 224 devvp = ump->um_devvp; 225 vn_lock(devvp, LK_EXCLUSIVE | LK_RETRY, p); 226 error = VOP_ACCESS(devvp, VREAD | VWRITE, 227 p->p_ucred, p); 228 if (error) { 229 VOP_UNLOCK(devvp, 0, p); 230 return (error); 231 } 232 VOP_UNLOCK(devvp, 0, p); 233 } 234 fs->e2fs_ronly = 0; 235 if (fs->e2fs.e2fs_state == E2FS_ISCLEAN) 236 fs->e2fs.e2fs_state = 0; 237 else 238 fs->e2fs.e2fs_state = E2FS_ERRORS; 239 fs->e2fs_fmod = 1; 240 } 241 if (args.fspec == 0) { 242 /* 243 * Process export requests. 244 */ 245 return (vfs_export(mp, &ump->um_export, 246 &args.export_info)); 247 } 248 } 249 /* 250 * Not an update, or updating the name: look up the name 251 * and verify that it refers to a sensible block device. 252 */ 253 NDINIT(ndp, LOOKUP, FOLLOW, UIO_USERSPACE, args.fspec, p); 254 if ((error = namei(ndp)) != 0) 255 return (error); 256 devvp = ndp->ni_vp; 257 258 if (devvp->v_type != VBLK) { 259 vrele(devvp); 260 return (ENOTBLK); 261 } 262 if (major(devvp->v_rdev) >= nblkdev) { 263 vrele(devvp); 264 return (ENXIO); 265 } 266 /* 267 * If mount by non-root, then verify that user has necessary 268 * permissions on the device. 269 */ 270 if (p->p_ucred->cr_uid != 0) { 271 accessmode = VREAD; 272 if ((mp->mnt_flag & MNT_RDONLY) == 0) 273 accessmode |= VWRITE; 274 vn_lock(devvp, LK_EXCLUSIVE | LK_RETRY, p); 275 error = VOP_ACCESS(devvp, accessmode, p->p_ucred, p); 276 if (error) { 277 vput(devvp); 278 return (error); 279 } 280 VOP_UNLOCK(devvp, 0, p); 281 } 282 if ((mp->mnt_flag & MNT_UPDATE) == 0) 283 error = ext2fs_mountfs(devvp, mp, p); 284 else { 285 if (devvp != ump->um_devvp) 286 error = EINVAL; /* XXX needs translation */ 287 else 288 vrele(devvp); 289 } 290 if (error) { 291 vrele(devvp); 292 return (error); 293 } 294 ump = VFSTOUFS(mp); 295 fs = ump->um_e2fs; 296 (void)copyinstr(path, fs->e2fs_fsmnt, sizeof(fs->e2fs_fsmnt) - 1, 297 &size); 298 bzero(fs->e2fs_fsmnt + size, sizeof(fs->e2fs_fsmnt) - size); 299 if (fs->e2fs.e2fs_rev > E2FS_REV0) { 300 (void)copystr(mp->mnt_stat.f_mntonname, fs->e2fs.e2fs_fsmnt, 301 sizeof(fs->e2fs.e2fs_fsmnt) - 1, &size); 302 bzero(fs->e2fs.e2fs_fsmnt, sizeof(fs->e2fs.e2fs_fsmnt) - size); 303 } 304 bcopy(fs->e2fs_fsmnt, mp->mnt_stat.f_mntonname, MNAMELEN); 305 (void)copyinstr(args.fspec, mp->mnt_stat.f_mntfromname, MNAMELEN - 1, 306 &size); 307 bzero(mp->mnt_stat.f_mntfromname + size, MNAMELEN - size); 308 if (fs->e2fs_fmod != 0) { /* XXX */ 309 fs->e2fs_fmod = 0; 310 if (fs->e2fs.e2fs_state == 0) 311 fs->e2fs.e2fs_wtime = time_second; 312 else 313 printf("%s: file system not clean; please fsck(8)\n", 314 mp->mnt_stat.f_mntfromname); 315 (void)ext2fs_cgupdate(ump, MNT_WAIT); 316 } 317 return (0); 318 } 319 320 int ext2fs_reload_vnode(struct vnode *, void *args); 321 322 struct ext2fs_reload_args { 323 struct m_ext2fs *fs; 324 struct proc *p; 325 struct ucred *cred; 326 struct vnode *devvp; 327 }; 328 329 int 330 ext2fs_reload_vnode(struct vnode *vp, void *args) 331 { 332 struct ext2fs_reload_args *era = args; 333 struct buf *bp; 334 struct inode *ip; 335 int error; 336 caddr_t cp; 337 338 /* 339 * Step 4: invalidate all inactive vnodes. 340 */ 341 if (vp->v_usecount == 0) { 342 vgonel(vp, era->p); 343 return (0); 344 } 345 346 /* 347 * Step 5: invalidate all cached file data. 348 */ 349 if (vget(vp, LK_EXCLUSIVE, era->p)) 350 return (0); 351 352 if (vinvalbuf(vp, 0, era->cred, era->p, 0, 0)) 353 panic("ext2fs_reload: dirty2"); 354 /* 355 * Step 6: re-read inode data for all active vnodes. 356 */ 357 ip = VTOI(vp); 358 error = bread(era->devvp, 359 fsbtodb(era->fs, ino_to_fsba(era->fs, ip->i_number)), 360 (int)era->fs->e2fs_bsize, NOCRED, &bp); 361 if (error) { 362 vput(vp); 363 return (error); 364 } 365 cp = (caddr_t)bp->b_data + 366 (ino_to_fsbo(era->fs, ip->i_number) * EXT2_DINODE_SIZE(era->fs)); 367 e2fs_iload((struct ext2fs_dinode *)cp, ip->i_e2din); 368 brelse(bp); 369 vput(vp); 370 return (0); 371 } 372 373 /* 374 * Reload all incore data for a filesystem (used after running fsck on 375 * the root filesystem and finding things to fix). The filesystem must 376 * be mounted read-only. 377 * 378 * Things to do to update the mount: 379 * 1) invalidate all cached meta-data. 380 * 2) re-read superblock from disk. 381 * 3) re-read summary information from disk. 382 * 4) invalidate all inactive vnodes. 383 * 5) invalidate all cached file data. 384 * 6) re-read inode data for all active vnodes. 385 */ 386 int 387 ext2fs_reload(struct mount *mountp, struct ucred *cred, struct proc *p) 388 { 389 struct vnode *devvp; 390 struct buf *bp; 391 struct m_ext2fs *fs; 392 struct ext2fs *newfs; 393 struct partinfo dpart; 394 int i, size, error; 395 struct ext2fs_reload_args era; 396 397 if ((mountp->mnt_flag & MNT_RDONLY) == 0) 398 return (EINVAL); 399 /* 400 * Step 1: invalidate all cached meta-data. 401 */ 402 devvp = VFSTOUFS(mountp)->um_devvp; 403 if (vinvalbuf(devvp, 0, cred, p, 0, 0)) 404 panic("ext2fs_reload: dirty1"); 405 406 /* 407 * Step 2: re-read superblock from disk. 408 */ 409 if (VOP_IOCTL(devvp, DIOCGPART, (caddr_t)&dpart, FREAD, NOCRED, p) != 0) 410 size = DEV_BSIZE; 411 else 412 size = dpart.disklab->d_secsize; 413 error = bread(devvp, (int32_t)(SBOFF / size), SBSIZE, NOCRED, &bp); 414 if (error) { 415 brelse(bp); 416 return (error); 417 } 418 newfs = (struct ext2fs *)bp->b_data; 419 error = ext2fs_checksb(newfs, (mountp->mnt_flag & MNT_RDONLY) != 0); 420 if (error) { 421 brelse(bp); 422 return (error); 423 } 424 425 fs = VFSTOUFS(mountp)->um_e2fs; 426 /* 427 * copy in new superblock, and compute in-memory values 428 */ 429 e2fs_sbload(newfs, &fs->e2fs); 430 fs->e2fs_ncg = 431 howmany(fs->e2fs.e2fs_bcount - fs->e2fs.e2fs_first_dblock, 432 fs->e2fs.e2fs_bpg); 433 /* XXX assume hw bsize = 512 */ 434 fs->e2fs_fsbtodb = fs->e2fs.e2fs_log_bsize + 1; 435 fs->e2fs_bsize = 1024 << fs->e2fs.e2fs_log_bsize; 436 fs->e2fs_bshift = LOG_MINBSIZE + fs->e2fs.e2fs_log_bsize; 437 fs->e2fs_qbmask = fs->e2fs_bsize - 1; 438 fs->e2fs_bmask = ~fs->e2fs_qbmask; 439 fs->e2fs_ngdb = howmany(fs->e2fs_ncg, 440 fs->e2fs_bsize / sizeof(struct ext2_gd)); 441 fs->e2fs_ipb = fs->e2fs_bsize / EXT2_DINODE_SIZE(fs); 442 fs->e2fs_itpg = fs->e2fs.e2fs_ipg/fs->e2fs_ipb; 443 444 /* 445 * Step 3: re-read summary information from disk. 446 */ 447 448 for (i=0; i < fs->e2fs_ngdb; i++) { 449 error = bread(devvp , 450 fsbtodb(fs, ((fs->e2fs_bsize>1024)? 0 : 1) + i + 1), 451 fs->e2fs_bsize, NOCRED, &bp); 452 if (error) { 453 brelse(bp); 454 return (error); 455 } 456 e2fs_cgload((struct ext2_gd*)bp->b_data, 457 &fs->e2fs_gd[i* fs->e2fs_bsize / sizeof(struct ext2_gd)], 458 fs->e2fs_bsize); 459 brelse(bp); 460 } 461 462 era.p = p; 463 era.cred = cred; 464 era.fs = fs; 465 era.devvp = devvp; 466 467 error = vfs_mount_foreach_vnode(mountp, ext2fs_reload_vnode, &era); 468 469 return (error); 470 } 471 472 /* 473 * Common code for mount and mountroot 474 */ 475 int 476 ext2fs_mountfs(struct vnode *devvp, struct mount *mp, struct proc *p) 477 { 478 struct ufsmount *ump; 479 struct buf *bp; 480 struct ext2fs *fs; 481 struct m_ext2fs *m_fs; 482 dev_t dev; 483 struct partinfo dpart; 484 int error, i, size, ronly; 485 struct ucred *cred; 486 487 dev = devvp->v_rdev; 488 cred = p ? p->p_ucred : NOCRED; 489 /* 490 * Disallow multiple mounts of the same device. 491 * Disallow mounting of a device that is currently in use 492 * (except for root, which might share swap device for miniroot). 493 * Flush out any old buffers remaining from a previous use. 494 */ 495 if ((error = vfs_mountedon(devvp)) != 0) 496 return (error); 497 if (vcount(devvp) > 1 && devvp != rootvp) 498 return (EBUSY); 499 if ((error = vinvalbuf(devvp, V_SAVE, cred, p, 0, 0)) != 0) 500 return (error); 501 502 ronly = (mp->mnt_flag & MNT_RDONLY) != 0; 503 error = VOP_OPEN(devvp, ronly ? FREAD : FREAD|FWRITE, FSCRED, p); 504 if (error) 505 return (error); 506 if (VOP_IOCTL(devvp, DIOCGPART, (caddr_t)&dpart, FREAD, cred, p) != 0) 507 size = DEV_BSIZE; 508 else 509 size = dpart.disklab->d_secsize; 510 511 bp = NULL; 512 ump = NULL; 513 514 #ifdef DEBUG_EXT2 515 printf("ext2 sb size: %d\n", sizeof(struct ext2fs)); 516 #endif 517 error = bread(devvp, (SBOFF / DEV_BSIZE), SBSIZE, cred, &bp); 518 if (error) 519 goto out; 520 fs = (struct ext2fs *)bp->b_data; 521 error = ext2fs_checksb(fs, ronly); 522 if (error) 523 goto out; 524 ump = malloc(sizeof *ump, M_UFSMNT, M_WAITOK | M_ZERO); 525 ump->um_e2fs = malloc(sizeof(struct m_ext2fs), M_UFSMNT, 526 M_WAITOK | M_ZERO); 527 e2fs_sbload((struct ext2fs*)bp->b_data, &ump->um_e2fs->e2fs); 528 brelse(bp); 529 bp = NULL; 530 m_fs = ump->um_e2fs; 531 m_fs->e2fs_ronly = ronly; 532 ump->um_fstype = UM_EXT2FS; 533 534 #ifdef DEBUG_EXT2 535 printf("ext2 ino size %d\n", EXT2_DINODE_SIZE(m_fs)); 536 #endif 537 if (ronly == 0) { 538 if (m_fs->e2fs.e2fs_state == E2FS_ISCLEAN) 539 m_fs->e2fs.e2fs_state = 0; 540 else 541 m_fs->e2fs.e2fs_state = E2FS_ERRORS; 542 m_fs->e2fs_fmod = 1; 543 } 544 545 /* compute dynamic sb infos */ 546 m_fs->e2fs_ncg = 547 howmany(m_fs->e2fs.e2fs_bcount - m_fs->e2fs.e2fs_first_dblock, 548 m_fs->e2fs.e2fs_bpg); 549 /* XXX assume hw bsize = 512 */ 550 m_fs->e2fs_fsbtodb = m_fs->e2fs.e2fs_log_bsize + 1; 551 m_fs->e2fs_bsize = 1024 << m_fs->e2fs.e2fs_log_bsize; 552 m_fs->e2fs_bshift = LOG_MINBSIZE + m_fs->e2fs.e2fs_log_bsize; 553 m_fs->e2fs_qbmask = m_fs->e2fs_bsize - 1; 554 m_fs->e2fs_bmask = ~m_fs->e2fs_qbmask; 555 m_fs->e2fs_ngdb = howmany(m_fs->e2fs_ncg, 556 m_fs->e2fs_bsize / sizeof(struct ext2_gd)); 557 m_fs->e2fs_ipb = m_fs->e2fs_bsize / EXT2_DINODE_SIZE(m_fs); 558 m_fs->e2fs_itpg = m_fs->e2fs.e2fs_ipg/m_fs->e2fs_ipb; 559 560 m_fs->e2fs_gd = malloc(m_fs->e2fs_ngdb * m_fs->e2fs_bsize, 561 M_UFSMNT, M_WAITOK); 562 for (i=0; i < m_fs->e2fs_ngdb; i++) { 563 error = bread(devvp , 564 fsbtodb(m_fs, ((m_fs->e2fs_bsize>1024)? 0 : 1) + i + 1), 565 m_fs->e2fs_bsize, NOCRED, &bp); 566 if (error) { 567 free(m_fs->e2fs_gd, M_UFSMNT); 568 goto out; 569 } 570 e2fs_cgload((struct ext2_gd*)bp->b_data, 571 &m_fs->e2fs_gd[i * m_fs->e2fs_bsize 572 / sizeof(struct ext2_gd)], 573 m_fs->e2fs_bsize); 574 brelse(bp); 575 bp = NULL; 576 } 577 578 mp->mnt_data = (qaddr_t)ump; 579 mp->mnt_stat.f_fsid.val[0] = (long)dev; 580 mp->mnt_stat.f_fsid.val[1] = mp->mnt_vfc->vfc_typenum; 581 mp->mnt_maxsymlinklen = EXT2_MAXSYMLINKLEN; 582 mp->mnt_flag |= MNT_LOCAL; 583 ump->um_mountp = mp; 584 ump->um_dev = dev; 585 ump->um_devvp = devvp; 586 ump->um_nindir = NINDIR(m_fs); 587 ump->um_bptrtodb = m_fs->e2fs_fsbtodb; 588 ump->um_seqinc = 1; /* no frags */ 589 devvp->v_specmountpoint = mp; 590 return (0); 591 out: 592 if (bp) 593 brelse(bp); 594 vn_lock(devvp, LK_EXCLUSIVE | LK_RETRY, p); 595 (void)VOP_CLOSE(devvp, ronly ? FREAD : FREAD|FWRITE, cred, p); 596 VOP_UNLOCK(devvp, 0, p); 597 if (ump) { 598 free(ump->um_e2fs, M_UFSMNT); 599 free(ump, M_UFSMNT); 600 mp->mnt_data = (qaddr_t)0; 601 } 602 return (error); 603 } 604 605 /* 606 * unmount system call 607 */ 608 int 609 ext2fs_unmount(struct mount *mp, int mntflags, struct proc *p) 610 { 611 struct ufsmount *ump; 612 struct m_ext2fs *fs; 613 int error, flags; 614 615 flags = 0; 616 if (mntflags & MNT_FORCE) 617 flags |= FORCECLOSE; 618 if ((error = ext2fs_flushfiles(mp, flags, p)) != 0) 619 return (error); 620 ump = VFSTOUFS(mp); 621 fs = ump->um_e2fs; 622 if (fs->e2fs_ronly == 0 && 623 ext2fs_cgupdate(ump, MNT_WAIT) == 0 && 624 (fs->e2fs.e2fs_state & E2FS_ERRORS) == 0) { 625 fs->e2fs.e2fs_state = E2FS_ISCLEAN; 626 (void) ext2fs_sbupdate(ump, MNT_WAIT); 627 } 628 629 if (ump->um_devvp->v_type != VBAD) 630 ump->um_devvp->v_specmountpoint = NULL; 631 vn_lock(ump->um_devvp, LK_EXCLUSIVE | LK_RETRY, p); 632 error = VOP_CLOSE(ump->um_devvp, fs->e2fs_ronly ? FREAD : FREAD|FWRITE, 633 NOCRED, p); 634 vput(ump->um_devvp); 635 free(fs->e2fs_gd, M_UFSMNT); 636 free(fs, M_UFSMNT); 637 free(ump, M_UFSMNT); 638 mp->mnt_data = (qaddr_t)0; 639 mp->mnt_flag &= ~MNT_LOCAL; 640 return (error); 641 } 642 643 /* 644 * Flush out all the files in a filesystem. 645 */ 646 int 647 ext2fs_flushfiles(struct mount *mp, int flags, struct proc *p) 648 { 649 struct ufsmount *ump; 650 int error; 651 652 ump = VFSTOUFS(mp); 653 /* 654 * Flush all the files. 655 */ 656 if ((error = vflush(mp, NULL, flags)) != 0) 657 return (error); 658 /* 659 * Flush filesystem metadata. 660 */ 661 vn_lock(ump->um_devvp, LK_EXCLUSIVE | LK_RETRY, p); 662 error = VOP_FSYNC(ump->um_devvp, p->p_ucred, MNT_WAIT, p); 663 VOP_UNLOCK(ump->um_devvp, 0, p); 664 return (error); 665 } 666 667 /* 668 * Get file system statistics. 669 */ 670 int 671 ext2fs_statfs(struct mount *mp, struct statfs *sbp, struct proc *p) 672 { 673 struct ufsmount *ump; 674 struct m_ext2fs *fs; 675 u_int32_t overhead, overhead_per_group; 676 int i, ngroups; 677 678 ump = VFSTOUFS(mp); 679 fs = ump->um_e2fs; 680 if (fs->e2fs.e2fs_magic != E2FS_MAGIC) 681 panic("ext2fs_statfs"); 682 683 /* 684 * Compute the overhead (FS structures) 685 */ 686 overhead_per_group = 1 /* block bitmap */ + 1 /* inode bitmap */ + 687 fs->e2fs_itpg; 688 overhead = fs->e2fs.e2fs_first_dblock + 689 fs->e2fs_ncg * overhead_per_group; 690 if (fs->e2fs.e2fs_rev > E2FS_REV0 && 691 fs->e2fs.e2fs_features_rocompat & EXT2F_ROCOMPAT_SPARSESUPER) { 692 for (i = 0, ngroups = 0; i < fs->e2fs_ncg; i++) { 693 if (cg_has_sb(i)) 694 ngroups++; 695 } 696 } else { 697 ngroups = fs->e2fs_ncg; 698 } 699 overhead += ngroups * (1 + fs->e2fs_ngdb); 700 701 sbp->f_bsize = fs->e2fs_bsize; 702 sbp->f_iosize = fs->e2fs_bsize; 703 sbp->f_blocks = fs->e2fs.e2fs_bcount - overhead; 704 sbp->f_bfree = fs->e2fs.e2fs_fbcount; 705 sbp->f_bavail = sbp->f_bfree - fs->e2fs.e2fs_rbcount; 706 sbp->f_files = fs->e2fs.e2fs_icount; 707 sbp->f_ffree = fs->e2fs.e2fs_ficount; 708 if (sbp != &mp->mnt_stat) { 709 bcopy(mp->mnt_stat.f_mntonname, sbp->f_mntonname, MNAMELEN); 710 bcopy(mp->mnt_stat.f_mntfromname, sbp->f_mntfromname, MNAMELEN); 711 } 712 strncpy(sbp->f_fstypename, mp->mnt_vfc->vfc_name, MFSNAMELEN); 713 return (0); 714 } 715 716 int ext2fs_sync_vnode(struct vnode *vp, void *); 717 718 struct ext2fs_sync_args { 719 int allerror; 720 int waitfor; 721 struct proc *p; 722 struct ucred *cred; 723 }; 724 725 int 726 ext2fs_sync_vnode(struct vnode *vp, void *args) 727 { 728 struct ext2fs_sync_args *esa = args; 729 struct inode *ip; 730 int error; 731 732 ip = VTOI(vp); 733 if (vp->v_type == VNON || 734 ((ip->i_flag & (IN_ACCESS | IN_CHANGE | IN_MODIFIED | IN_UPDATE)) == 0 && 735 LIST_EMPTY(&vp->v_dirtyblkhd)) || 736 esa->waitfor == MNT_LAZY) { 737 return (0); 738 } 739 740 if (vget(vp, LK_EXCLUSIVE | LK_NOWAIT, esa->p)) 741 return (0); 742 743 if ((error = VOP_FSYNC(vp, esa->cred, esa->waitfor, esa->p)) != 0) 744 esa->allerror = error; 745 vput(vp); 746 return (0); 747 } 748 /* 749 * Go through the disk queues to initiate sandbagged IO; 750 * go through the inodes to write those that have been modified; 751 * initiate the writing of the super block if it has been modified. 752 * 753 * Should always be called with the mount point locked. 754 */ 755 int 756 ext2fs_sync(struct mount *mp, int waitfor, struct ucred *cred, struct proc *p) 757 { 758 struct ufsmount *ump = VFSTOUFS(mp); 759 struct m_ext2fs *fs; 760 int error, allerror = 0; 761 struct ext2fs_sync_args esa; 762 763 fs = ump->um_e2fs; 764 if (fs->e2fs_ronly != 0) { /* XXX */ 765 printf("fs = %s\n", fs->e2fs_fsmnt); 766 panic("update: rofs mod"); 767 } 768 769 /* 770 * Write back each (modified) inode. 771 */ 772 esa.p = p; 773 esa.cred = cred; 774 esa.allerror = 0; 775 esa.waitfor = waitfor; 776 777 vfs_mount_foreach_vnode(mp, ext2fs_sync_vnode, &esa); 778 if (esa.allerror != 0) 779 allerror = esa.allerror; 780 781 /* 782 * Force stale file system control information to be flushed. 783 */ 784 if (waitfor != MNT_LAZY) { 785 vn_lock(ump->um_devvp, LK_EXCLUSIVE | LK_RETRY, p); 786 if ((error = VOP_FSYNC(ump->um_devvp, cred, waitfor, p)) != 0) 787 allerror = error; 788 VOP_UNLOCK(ump->um_devvp, 0, p); 789 } 790 /* 791 * Write back modified superblock. 792 */ 793 if (fs->e2fs_fmod != 0) { 794 fs->e2fs_fmod = 0; 795 fs->e2fs.e2fs_wtime = time_second; 796 if ((error = ext2fs_cgupdate(ump, waitfor))) 797 allerror = error; 798 } 799 return (allerror); 800 } 801 802 /* 803 * Look up a EXT2FS dinode number to find its incore vnode, otherwise read it 804 * in from disk. If it is in core, wait for the lock bit to clear, then 805 * return the inode locked. Detection and handling of mount points must be 806 * done by the calling routine. 807 */ 808 int 809 ext2fs_vget(struct mount *mp, ino_t ino, struct vnode **vpp) 810 { 811 struct m_ext2fs *fs; 812 struct inode *ip; 813 struct ext2fs_dinode *dp; 814 struct ufsmount *ump; 815 struct buf *bp; 816 struct vnode *vp; 817 dev_t dev; 818 int error; 819 820 ump = VFSTOUFS(mp); 821 dev = ump->um_dev; 822 823 retry: 824 if ((*vpp = ufs_ihashget(dev, ino)) != NULL) 825 return (0); 826 827 /* Allocate a new vnode/inode. */ 828 if ((error = getnewvnode(VT_EXT2FS, mp, ext2fs_vnodeop_p, &vp)) != 0) { 829 *vpp = NULL; 830 return (error); 831 } 832 833 ip = pool_get(&ext2fs_inode_pool, PR_WAITOK|PR_ZERO); 834 lockinit(&ip->i_lock, PINOD, "inode", 0, 0); 835 vp->v_data = ip; 836 ip->i_vnode = vp; 837 ip->i_ump = ump; 838 ip->i_e2fs = fs = ump->um_e2fs; 839 ip->i_dev = dev; 840 ip->i_number = ino; 841 ip->i_e2fs_last_lblk = 0; 842 ip->i_e2fs_last_blk = 0; 843 844 /* 845 * Put it onto its hash chain and lock it so that other requests for 846 * this inode will block if they arrive while we are sleeping waiting 847 * for old data structures to be purged or for the contents of the 848 * disk portion of this inode to be read. 849 */ 850 error = ufs_ihashins(ip); 851 852 if (error) { 853 vrele(vp); 854 855 if (error == EEXIST) 856 goto retry; 857 858 return (error); 859 } 860 861 /* Read in the disk contents for the inode, copy into the inode. */ 862 error = bread(ump->um_devvp, fsbtodb(fs, ino_to_fsba(fs, ino)), 863 (int)fs->e2fs_bsize, NOCRED, &bp); 864 if (error) { 865 /* 866 * The inode does not contain anything useful, so it would 867 * be misleading to leave it on its hash chain. With mode 868 * still zero, it will be unlinked and returned to the free 869 * list by vput(). 870 */ 871 vput(vp); 872 brelse(bp); 873 *vpp = NULL; 874 return (error); 875 } 876 877 dp = (struct ext2fs_dinode *) ((char *)bp->b_data 878 + EXT2_DINODE_SIZE(fs) * ino_to_fsbo(fs, ino)); 879 880 ip->i_e2din = pool_get(&ext2fs_dinode_pool, PR_WAITOK); 881 e2fs_iload(dp, ip->i_e2din); 882 brelse(bp); 883 884 ip->i_effnlink = ip->i_e2fs_nlink; 885 886 /* 887 * The fields for storing the UID and GID of an ext2fs inode are 888 * limited to 16 bits. To overcome this limitation, Linux decided to 889 * scatter the highest bits of these values into a previously reserved 890 * area on the disk inode. We deal with this situation by having two 891 * 32-bit fields *out* of the disk inode to hold the complete values. 892 * Now that we are reading in the inode, compute these fields. 893 */ 894 ip->i_e2fs_uid = ip->i_e2fs_uid_low | (ip->i_e2fs_uid_high << 16); 895 ip->i_e2fs_gid = ip->i_e2fs_gid_low | (ip->i_e2fs_gid_high << 16); 896 897 /* If the inode was deleted, reset all fields */ 898 if (ip->i_e2fs_dtime != 0) { 899 ip->i_e2fs_mode = ip->i_e2fs_nblock = 0; 900 (void)ext2fs_setsize(ip, 0); 901 } 902 903 /* 904 * Initialize the vnode from the inode, check for aliases. 905 * Note that the underlying vnode may have changed. 906 */ 907 error = ext2fs_vinit(mp, ext2fs_specop_p, EXT2FS_FIFOOPS, &vp); 908 if (error) { 909 vput(vp); 910 *vpp = NULL; 911 return (error); 912 } 913 914 /* 915 * Finish inode initialization now that aliasing has been resolved. 916 */ 917 vref(ip->i_devvp); 918 /* 919 * Set up a generation number for this inode if it does not 920 * already have one. This should only happen on old filesystems. 921 */ 922 if (ip->i_e2fs_gen == 0) { 923 if (++ext2gennumber < (u_long)time_second) 924 ext2gennumber = time_second; 925 ip->i_e2fs_gen = ext2gennumber; 926 if ((vp->v_mount->mnt_flag & MNT_RDONLY) == 0) 927 ip->i_flag |= IN_MODIFIED; 928 } 929 930 *vpp = vp; 931 return (0); 932 } 933 934 /* 935 * File handle to vnode 936 * 937 * Have to be really careful about stale file handles: 938 * - check that the inode number is valid 939 * - call ext2fs_vget() to get the locked inode 940 * - check for an unallocated inode (i_mode == 0) 941 * - check that the given client host has export rights and return 942 * those rights via. exflagsp and credanonp 943 */ 944 int 945 ext2fs_fhtovp(struct mount *mp, struct fid *fhp, struct vnode **vpp) 946 { 947 struct inode *ip; 948 struct vnode *nvp; 949 int error; 950 struct ufid *ufhp; 951 struct m_ext2fs *fs; 952 953 ufhp = (struct ufid *)fhp; 954 fs = VFSTOUFS(mp)->um_e2fs; 955 if ((ufhp->ufid_ino < EXT2_FIRSTINO && ufhp->ufid_ino != EXT2_ROOTINO) || 956 ufhp->ufid_ino > fs->e2fs_ncg * fs->e2fs.e2fs_ipg) 957 return (ESTALE); 958 959 if ((error = VFS_VGET(mp, ufhp->ufid_ino, &nvp)) != 0) { 960 *vpp = NULLVP; 961 return (error); 962 } 963 ip = VTOI(nvp); 964 if (ip->i_e2fs_mode == 0 || ip->i_e2fs_dtime != 0 || 965 ip->i_e2fs_gen != ufhp->ufid_gen) { 966 vput(nvp); 967 *vpp = NULLVP; 968 return (ESTALE); 969 } 970 *vpp = nvp; 971 return (0); 972 } 973 974 /* 975 * Vnode pointer to File handle 976 */ 977 /* ARGSUSED */ 978 int 979 ext2fs_vptofh(struct vnode *vp, struct fid *fhp) 980 { 981 struct inode *ip; 982 struct ufid *ufhp; 983 984 ip = VTOI(vp); 985 ufhp = (struct ufid *)fhp; 986 ufhp->ufid_len = sizeof(struct ufid); 987 ufhp->ufid_ino = ip->i_number; 988 ufhp->ufid_gen = ip->i_e2fs_gen; 989 return (0); 990 } 991 992 /* 993 * no sysctl for ext2fs 994 */ 995 996 int 997 ext2fs_sysctl(int *name, u_int namelen, void *oldp, size_t *oldlenp, 998 void *newp, size_t newlen, struct proc *p) 999 { 1000 return (EOPNOTSUPP); 1001 } 1002 1003 /* 1004 * Write a superblock and associated information back to disk. 1005 */ 1006 int 1007 ext2fs_sbupdate(struct ufsmount *mp, int waitfor) 1008 { 1009 struct m_ext2fs *fs = mp->um_e2fs; 1010 struct buf *bp; 1011 int error = 0; 1012 1013 bp = getblk(mp->um_devvp, SBLOCK, SBSIZE, 0, 0); 1014 e2fs_sbsave(&fs->e2fs, (struct ext2fs *) bp->b_data); 1015 if (waitfor == MNT_WAIT) 1016 error = bwrite(bp); 1017 else 1018 bawrite(bp); 1019 return (error); 1020 } 1021 1022 int 1023 ext2fs_cgupdate(struct ufsmount *mp, int waitfor) 1024 { 1025 struct m_ext2fs *fs = mp->um_e2fs; 1026 struct buf *bp; 1027 int i, error = 0, allerror = 0; 1028 1029 allerror = ext2fs_sbupdate(mp, waitfor); 1030 for (i = 0; i < fs->e2fs_ngdb; i++) { 1031 bp = getblk(mp->um_devvp, fsbtodb(fs, ((fs->e2fs_bsize>1024)?0:1)+i+1), 1032 fs->e2fs_bsize, 0, 0); 1033 e2fs_cgsave(&fs->e2fs_gd[i* fs->e2fs_bsize / sizeof(struct ext2_gd)], (struct ext2_gd*)bp->b_data, fs->e2fs_bsize); 1034 if (waitfor == MNT_WAIT) 1035 error = bwrite(bp); 1036 else 1037 bawrite(bp); 1038 } 1039 1040 if (!allerror && error) 1041 allerror = error; 1042 return (allerror); 1043 } 1044 1045 static int 1046 ext2fs_checksb(struct ext2fs *fs, int ronly) 1047 { 1048 if (fs2h16(fs->e2fs_magic) != E2FS_MAGIC) { 1049 return (EIO); /* XXX needs translation */ 1050 } 1051 if (fs2h32(fs->e2fs_rev) > E2FS_REV1) { 1052 #ifdef DIAGNOSTIC 1053 printf("Ext2 fs: unsupported revision number: %x\n", 1054 fs2h32(fs->e2fs_rev)); 1055 #endif 1056 return (EIO); /* XXX needs translation */ 1057 } 1058 if (fs2h32(fs->e2fs_log_bsize) > 2) { /* block size = 1024|2048|4096 */ 1059 #ifdef DIAGNOSTIC 1060 printf("Ext2 fs: bad block size: %d (expected <=2 for ext2 fs)\n", 1061 fs2h32(fs->e2fs_log_bsize)); 1062 #endif 1063 return (EIO); /* XXX needs translation */ 1064 } 1065 if (fs2h32(fs->e2fs_rev) > E2FS_REV0) { 1066 if (fs2h32(fs->e2fs_first_ino) != EXT2_FIRSTINO) { 1067 printf("Ext2 fs: unsupported first inode position"); 1068 return (EINVAL); /* XXX needs translation */ 1069 } 1070 if (fs2h32(fs->e2fs_features_incompat) & 1071 ~EXT2F_INCOMPAT_SUPP) { 1072 printf("Ext2 fs: unsupported optional feature\n"); 1073 return (EINVAL); /* XXX needs translation */ 1074 } 1075 if (!ronly && fs2h32(fs->e2fs_features_rocompat) & 1076 ~EXT2F_ROCOMPAT_SUPP) { 1077 return (EROFS); /* XXX needs translation */ 1078 } 1079 } 1080 return (0); 1081 } 1082