1 1.19 hannken /* $NetBSD: v7fs_vfsops.c,v 1.19 2022/05/03 07:34:38 hannken Exp $ */ 2 1.1 uch 3 1.1 uch /*- 4 1.1 uch * Copyright (c) 2004, 2011 The NetBSD Foundation, Inc. 5 1.1 uch * All rights reserved. 6 1.1 uch * 7 1.1 uch * This code is derived from software contributed to The NetBSD Foundation 8 1.1 uch * by UCHIYAMA Yasushi. 9 1.1 uch * 10 1.1 uch * Redistribution and use in source and binary forms, with or without 11 1.1 uch * modification, are permitted provided that the following conditions 12 1.1 uch * are met: 13 1.1 uch * 1. Redistributions of source code must retain the above copyright 14 1.1 uch * notice, this list of conditions and the following disclaimer. 15 1.1 uch * 2. Redistributions in binary form must reproduce the above copyright 16 1.1 uch * notice, this list of conditions and the following disclaimer in the 17 1.1 uch * documentation and/or other materials provided with the distribution. 18 1.1 uch * 19 1.1 uch * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 20 1.1 uch * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 21 1.1 uch * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 22 1.1 uch * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 23 1.1 uch * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 24 1.1 uch * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 25 1.1 uch * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 26 1.1 uch * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 27 1.1 uch * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 28 1.1 uch * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 29 1.1 uch * POSSIBILITY OF SUCH DAMAGE. 30 1.1 uch */ 31 1.1 uch 32 1.1 uch #include <sys/cdefs.h> 33 1.19 hannken __KERNEL_RCSID(0, "$NetBSD: v7fs_vfsops.c,v 1.19 2022/05/03 07:34:38 hannken Exp $"); 34 1.1 uch #if defined _KERNEL_OPT 35 1.1 uch #include "opt_v7fs.h" 36 1.1 uch #endif 37 1.1 uch 38 1.1 uch #include <sys/types.h> 39 1.1 uch #include <sys/param.h> 40 1.1 uch #include <sys/systm.h> 41 1.1 uch #include <sys/pool.h> 42 1.1 uch #include <sys/time.h> 43 1.1 uch #include <sys/ucred.h> 44 1.1 uch #include <sys/mount.h> 45 1.5 christos #include <sys/disk.h> 46 1.5 christos #include <sys/device.h> 47 1.1 uch #include <sys/fcntl.h> 48 1.8 rmind #include <sys/kmem.h> 49 1.1 uch #include <sys/kauth.h> 50 1.1 uch #include <sys/proc.h> 51 1.1 uch 52 1.1 uch /* v-node */ 53 1.1 uch #include <sys/namei.h> 54 1.1 uch #include <sys/vnode.h> 55 1.1 uch /* devsw */ 56 1.1 uch #include <sys/conf.h> 57 1.1 uch 58 1.1 uch #include "v7fs_extern.h" 59 1.1 uch #include "v7fs.h" 60 1.1 uch #include "v7fs_impl.h" 61 1.1 uch #include "v7fs_inode.h" 62 1.1 uch #include "v7fs_superblock.h" 63 1.1 uch 64 1.1 uch #ifdef V7FS_VFSOPS_DEBUG 65 1.1 uch #define DPRINTF(fmt, args...) printf("%s: " fmt, __func__, ##args) 66 1.1 uch #else 67 1.1 uch #define DPRINTF(arg...) ((void)0) 68 1.1 uch #endif 69 1.1 uch 70 1.1 uch struct pool v7fs_node_pool; 71 1.1 uch 72 1.1 uch static int v7fs_mountfs(struct vnode *, struct mount *, int); 73 1.1 uch static int v7fs_openfs(struct vnode *, struct mount *, struct lwp *); 74 1.1 uch static void v7fs_closefs(struct vnode *, struct mount *); 75 1.2 uch static int is_v7fs_partition(struct vnode *); 76 1.1 uch static enum vtype v7fs_mode_to_vtype(v7fs_mode_t mode); 77 1.1 uch 78 1.1 uch int 79 1.1 uch v7fs_mount(struct mount *mp, const char *path, void *data, size_t *data_len) 80 1.1 uch { 81 1.1 uch struct lwp *l = curlwp; 82 1.1 uch struct v7fs_args *args = data; 83 1.1 uch struct v7fs_mount *v7fsmount = (void *)mp->mnt_data; 84 1.1 uch struct vnode *devvp = NULL; 85 1.7 joerg int error = 0; 86 1.1 uch bool update = mp->mnt_flag & MNT_UPDATE; 87 1.1 uch 88 1.1 uch DPRINTF("mnt_flag=%x %s\n", mp->mnt_flag, update ? "update" : ""); 89 1.1 uch 90 1.10 maxv if (args == NULL) 91 1.10 maxv return EINVAL; 92 1.1 uch if (*data_len < sizeof(*args)) 93 1.1 uch return EINVAL; 94 1.1 uch 95 1.1 uch if (mp->mnt_flag & MNT_GETARGS) { 96 1.1 uch if (!v7fsmount) 97 1.1 uch return EIO; 98 1.1 uch args->fspec = NULL; 99 1.1 uch args->endian = v7fsmount->core->endian; 100 1.1 uch *data_len = sizeof(*args); 101 1.1 uch return 0; 102 1.1 uch } 103 1.1 uch 104 1.1 uch DPRINTF("args->fspec=%s endian=%d\n", args->fspec, args->endian); 105 1.1 uch if (args->fspec == NULL) { 106 1.1 uch /* nothing to do. */ 107 1.1 uch return EINVAL; 108 1.1 uch } 109 1.1 uch 110 1.1 uch if (args->fspec != NULL) { 111 1.1 uch /* Look up the name and verify that it's sane. */ 112 1.1 uch error = namei_simple_user(args->fspec, 113 1.1 uch NSM_FOLLOW_NOEMULROOT, &devvp); 114 1.1 uch if (error != 0) 115 1.1 uch return (error); 116 1.1 uch DPRINTF("mount device=%lx\n", (long)devvp->v_rdev); 117 1.1 uch 118 1.1 uch if (!update) { 119 1.1 uch /* 120 1.1 uch * Be sure this is a valid block device 121 1.1 uch */ 122 1.1 uch if (devvp->v_type != VBLK) 123 1.1 uch error = ENOTBLK; 124 1.1 uch else if (bdevsw_lookup(devvp->v_rdev) == NULL) 125 1.1 uch error = ENXIO; 126 1.1 uch } else { 127 1.1 uch KDASSERT(v7fsmount); 128 1.1 uch /* 129 1.1 uch * Be sure we're still naming the same device 130 1.1 uch * used for our initial mount 131 1.1 uch */ 132 1.1 uch if (devvp != v7fsmount->devvp) { 133 1.1 uch DPRINTF("devvp %p != %p rootvp=%p\n", devvp, 134 1.1 uch v7fsmount->devvp, rootvp); 135 1.1 uch if (rootvp == v7fsmount->devvp) { 136 1.1 uch vrele(devvp); 137 1.1 uch devvp = rootvp; 138 1.1 uch vref(devvp); 139 1.1 uch } else { 140 1.1 uch error = EINVAL; 141 1.1 uch } 142 1.1 uch } 143 1.1 uch } 144 1.1 uch } 145 1.1 uch 146 1.1 uch /* 147 1.1 uch * If mount by non-root, then verify that user has necessary 148 1.1 uch * permissions on the device. 149 1.1 uch * 150 1.1 uch * Permission to update a mount is checked higher, so here we presume 151 1.1 uch * updating the mount is okay (for example, as far as securelevel goes) 152 1.1 uch * which leaves us with the normal check. 153 1.1 uch */ 154 1.1 uch if (error == 0) { 155 1.1 uch int accessmode = VREAD; 156 1.1 uch if (update ? 157 1.1 uch (mp->mnt_iflag & IMNT_WANTRDWR) != 0 : 158 1.1 uch (mp->mnt_flag & MNT_RDONLY) == 0) 159 1.1 uch accessmode |= VWRITE; 160 1.19 hannken 161 1.19 hannken vn_lock(devvp, LK_EXCLUSIVE | LK_RETRY); 162 1.6 elad error = kauth_authorize_system(l->l_cred, KAUTH_SYSTEM_MOUNT, 163 1.6 elad KAUTH_REQ_SYSTEM_MOUNT_DEVICE, mp, devvp, 164 1.6 elad KAUTH_ARG(accessmode)); 165 1.19 hannken VOP_UNLOCK(devvp); 166 1.1 uch } 167 1.1 uch 168 1.1 uch if (error) { 169 1.1 uch vrele(devvp); 170 1.1 uch return error; 171 1.1 uch } 172 1.1 uch 173 1.1 uch if (!update) { 174 1.1 uch if ((error = v7fs_openfs(devvp, mp, l))) { 175 1.1 uch vrele(devvp); 176 1.1 uch return error; 177 1.1 uch } 178 1.1 uch 179 1.1 uch if ((error = v7fs_mountfs(devvp, mp, args->endian))) { 180 1.1 uch v7fs_closefs(devvp, mp); 181 1.1 uch VOP_UNLOCK(devvp); 182 1.1 uch vrele(devvp); 183 1.1 uch return error; 184 1.1 uch } 185 1.1 uch VOP_UNLOCK(devvp); 186 1.1 uch } else if (mp->mnt_flag & MNT_RDONLY) { 187 1.1 uch /* XXX: r/w -> read only */ 188 1.1 uch } 189 1.1 uch 190 1.1 uch return set_statvfs_info(path, UIO_USERSPACE, args->fspec, UIO_USERSPACE, 191 1.1 uch mp->mnt_op->vfs_name, mp, l); 192 1.1 uch } 193 1.1 uch 194 1.2 uch static int 195 1.1 uch is_v7fs_partition(struct vnode *devvp) 196 1.1 uch { 197 1.5 christos struct dkwedge_info dkw; 198 1.1 uch int error; 199 1.1 uch 200 1.5 christos if ((error = getdiskinfo(devvp, &dkw)) != 0) { 201 1.5 christos DPRINTF("getdiskinfo=%d\n", error); 202 1.2 uch return error; 203 1.1 uch } 204 1.18 zafer DPRINTF("ptype=%s size=%" PRIu64 "\n", dkw.dkw_ptype, dkw.dkw_size); 205 1.1 uch 206 1.5 christos return strcmp(dkw.dkw_ptype, DKW_PTYPE_V7) == 0 ? 0 : EINVAL; 207 1.1 uch } 208 1.1 uch 209 1.1 uch static int 210 1.1 uch v7fs_openfs(struct vnode *devvp, struct mount *mp, struct lwp *l) 211 1.1 uch { 212 1.1 uch kauth_cred_t cred = l->l_cred; 213 1.1 uch int oflags; 214 1.1 uch int error; 215 1.1 uch 216 1.1 uch /* Flush buffer */ 217 1.1 uch vn_lock(devvp, LK_EXCLUSIVE | LK_RETRY); 218 1.1 uch if ((error = vinvalbuf(devvp, V_SAVE, cred, l, 0, 0))) 219 1.1 uch goto unlock_exit; 220 1.1 uch 221 1.1 uch /* Open block device */ 222 1.1 uch oflags = FREAD; 223 1.1 uch if ((mp->mnt_flag & MNT_RDONLY) == 0) 224 1.1 uch oflags |= FWRITE; 225 1.1 uch 226 1.1 uch if ((error = VOP_OPEN(devvp, oflags, NOCRED)) != 0) { 227 1.1 uch DPRINTF("VOP_OPEN=%d\n", error); 228 1.1 uch goto unlock_exit; 229 1.1 uch } 230 1.1 uch 231 1.1 uch return 0; /* lock held */ 232 1.1 uch 233 1.1 uch unlock_exit: 234 1.1 uch VOP_UNLOCK(devvp); 235 1.1 uch 236 1.1 uch return error; 237 1.1 uch } 238 1.1 uch 239 1.1 uch static void 240 1.1 uch v7fs_closefs(struct vnode *devvp, struct mount *mp) 241 1.1 uch { 242 1.1 uch int oflags = FREAD; 243 1.1 uch 244 1.1 uch if ((mp->mnt_flag & MNT_RDONLY) == 0) 245 1.1 uch oflags |= FWRITE; 246 1.1 uch 247 1.1 uch VOP_CLOSE(devvp, oflags, NOCRED); 248 1.1 uch } 249 1.1 uch 250 1.1 uch static int 251 1.1 uch v7fs_mountfs(struct vnode *devvp, struct mount *mp, int endian) 252 1.1 uch { 253 1.1 uch struct v7fs_mount *v7fsmount; 254 1.1 uch int error; 255 1.1 uch struct v7fs_mount_device mount; 256 1.1 uch 257 1.1 uch DPRINTF("%d\n",endian); 258 1.1 uch 259 1.8 rmind v7fsmount = kmem_zalloc(sizeof(*v7fsmount), KM_SLEEP); 260 1.1 uch v7fsmount->devvp = devvp; 261 1.1 uch v7fsmount->mountp = mp; 262 1.1 uch 263 1.1 uch mount.device.vnode = devvp; 264 1.1 uch mount.endian = endian; 265 1.1 uch 266 1.1 uch if ((error = v7fs_io_init(&v7fsmount->core, &mount, V7FS_BSIZE))) { 267 1.1 uch goto err_exit; 268 1.1 uch } 269 1.1 uch struct v7fs_self *fs = v7fsmount->core; 270 1.1 uch 271 1.1 uch if ((error = v7fs_superblock_load(fs))) { 272 1.1 uch v7fs_io_fini(fs); 273 1.1 uch goto err_exit; 274 1.1 uch } 275 1.1 uch 276 1.1 uch mp->mnt_data = v7fsmount; 277 1.1 uch mp->mnt_stat.f_fsidx.__fsid_val[0] = (long)devvp->v_rdev; 278 1.1 uch mp->mnt_stat.f_fsidx.__fsid_val[1] = makefstype(MOUNT_V7FS); 279 1.1 uch mp->mnt_stat.f_fsid = mp->mnt_stat.f_fsidx.__fsid_val[0]; 280 1.1 uch mp->mnt_stat.f_namemax = V7FS_NAME_MAX; 281 1.1 uch mp->mnt_flag |= MNT_LOCAL; 282 1.1 uch mp->mnt_dev_bshift = V7FS_BSHIFT; 283 1.1 uch mp->mnt_fs_bshift = V7FS_BSHIFT; 284 1.1 uch 285 1.1 uch return 0; 286 1.1 uch 287 1.1 uch err_exit: 288 1.8 rmind kmem_free(v7fsmount, sizeof(*v7fsmount)); 289 1.1 uch return error; 290 1.1 uch } 291 1.1 uch 292 1.1 uch int 293 1.1 uch v7fs_start(struct mount *mp, int flags) 294 1.1 uch { 295 1.1 uch 296 1.1 uch DPRINTF("\n"); 297 1.1 uch /* Nothing to do. */ 298 1.1 uch return 0; 299 1.1 uch } 300 1.1 uch 301 1.1 uch int 302 1.1 uch v7fs_unmount(struct mount *mp, int mntflags) 303 1.1 uch { 304 1.1 uch struct v7fs_mount *v7fsmount = (void *)mp->mnt_data; 305 1.1 uch int error; 306 1.1 uch 307 1.1 uch DPRINTF("%p\n", v7fsmount); 308 1.1 uch 309 1.1 uch if ((error = vflush(mp, NULLVP, 310 1.1 uch mntflags & MNT_FORCE ? FORCECLOSE : 0)) != 0) 311 1.1 uch return error; 312 1.1 uch 313 1.1 uch vn_lock(v7fsmount->devvp, LK_EXCLUSIVE | LK_RETRY); 314 1.1 uch error = VOP_CLOSE(v7fsmount->devvp, FREAD, NOCRED); 315 1.1 uch vput(v7fsmount->devvp); 316 1.1 uch 317 1.1 uch v7fs_io_fini(v7fsmount->core); 318 1.1 uch 319 1.8 rmind kmem_free(v7fsmount, sizeof(*v7fsmount)); 320 1.1 uch mp->mnt_data = NULL; 321 1.1 uch mp->mnt_flag &= ~MNT_LOCAL; 322 1.1 uch 323 1.1 uch return 0; 324 1.1 uch } 325 1.1 uch 326 1.1 uch int 327 1.17 ad v7fs_root(struct mount *mp, int lktype, struct vnode **vpp) 328 1.1 uch { 329 1.1 uch struct vnode *vp; 330 1.1 uch int error; 331 1.1 uch 332 1.1 uch DPRINTF("\n"); 333 1.17 ad if ((error = VFS_VGET(mp, V7FS_ROOT_INODE, lktype, &vp)) != 0) { 334 1.1 uch DPRINTF("error=%d\n", error); 335 1.1 uch return error; 336 1.1 uch } 337 1.1 uch *vpp = vp; 338 1.1 uch DPRINTF("done.\n"); 339 1.1 uch 340 1.1 uch return 0; 341 1.1 uch } 342 1.1 uch 343 1.1 uch int 344 1.1 uch v7fs_statvfs(struct mount *mp, struct statvfs *f) 345 1.1 uch { 346 1.1 uch struct v7fs_mount *v7fsmount = mp->mnt_data; 347 1.1 uch struct v7fs_self *fs = v7fsmount->core; 348 1.1 uch 349 1.1 uch DPRINTF("scratch remain=%d\n", fs->scratch_remain); 350 1.1 uch 351 1.1 uch v7fs_superblock_status(fs); 352 1.1 uch 353 1.1 uch f->f_bsize = V7FS_BSIZE; 354 1.1 uch f->f_frsize = V7FS_BSIZE; 355 1.1 uch f->f_iosize = V7FS_BSIZE; 356 1.1 uch f->f_blocks = fs->stat.total_blocks; 357 1.1 uch f->f_bfree = fs->stat.free_blocks; 358 1.1 uch f->f_bavail = fs->stat.free_blocks; 359 1.1 uch f->f_bresvd = 0; 360 1.1 uch f->f_files = fs->stat.total_files; 361 1.1 uch f->f_ffree = fs->stat.free_inode; 362 1.1 uch f->f_favail = f->f_ffree; 363 1.1 uch f->f_fresvd = 0; 364 1.1 uch copy_statvfs_info(f, mp); 365 1.1 uch 366 1.1 uch return 0; 367 1.1 uch } 368 1.1 uch 369 1.12 hannken static bool 370 1.12 hannken v7fs_sync_selector(void *cl, struct vnode *vp) 371 1.12 hannken { 372 1.13 riastrad struct v7fs_node *v7fs_node; 373 1.13 riastrad 374 1.13 riastrad KASSERT(mutex_owned(vp->v_interlock)); 375 1.12 hannken 376 1.13 riastrad v7fs_node = vp->v_data; 377 1.12 hannken if (v7fs_node == NULL) 378 1.12 hannken return false; 379 1.12 hannken if (!v7fs_inode_allocated(&v7fs_node->inode)) 380 1.12 hannken return false; 381 1.12 hannken 382 1.12 hannken return true; 383 1.12 hannken } 384 1.12 hannken 385 1.1 uch int 386 1.1 uch v7fs_sync(struct mount *mp, int waitfor, kauth_cred_t cred) 387 1.1 uch { 388 1.1 uch struct v7fs_mount *v7fsmount = mp->mnt_data; 389 1.1 uch struct v7fs_self *fs = v7fsmount->core; 390 1.12 hannken struct vnode_iterator *marker; 391 1.12 hannken struct vnode *vp; 392 1.1 uch int err, error; 393 1.1 uch 394 1.1 uch DPRINTF("\n"); 395 1.1 uch 396 1.1 uch v7fs_superblock_writeback(fs); 397 1.12 hannken error = 0; 398 1.12 hannken vfs_vnode_iterator_init(mp, &marker); 399 1.12 hannken while ((vp = vfs_vnode_iterator_next(marker, 400 1.12 hannken v7fs_sync_selector, NULL)) != NULL) { 401 1.12 hannken err = vn_lock(vp, LK_EXCLUSIVE); 402 1.12 hannken if (err) { 403 1.12 hannken vrele(vp); 404 1.12 hannken continue; 405 1.1 uch } 406 1.12 hannken err = VOP_FSYNC(vp, cred, FSYNC_WAIT, 0, 0); 407 1.12 hannken vput(vp); 408 1.12 hannken if (err != 0) 409 1.12 hannken error = err; 410 1.1 uch } 411 1.12 hannken vfs_vnode_iterator_destroy(marker); 412 1.1 uch 413 1.1 uch return error; 414 1.1 uch } 415 1.1 uch 416 1.1 uch static enum vtype 417 1.1 uch v7fs_mode_to_vtype (v7fs_mode_t mode) 418 1.1 uch { 419 1.1 uch enum vtype table[] = { VCHR, VDIR, VBLK, VREG, VLNK, VSOCK }; 420 1.1 uch 421 1.1 uch if ((mode & V7FS_IFMT) == V7FSBSD_IFFIFO) 422 1.1 uch return VFIFO; 423 1.1 uch 424 1.1 uch return table[((mode >> 13) & 7) - 1]; 425 1.1 uch } 426 1.1 uch 427 1.1 uch int 428 1.12 hannken v7fs_loadvnode(struct mount *mp, struct vnode *vp, 429 1.12 hannken const void *key, size_t key_len, const void **new_key) 430 1.1 uch { 431 1.12 hannken struct v7fs_mount *v7fsmount; 432 1.12 hannken struct v7fs_self *fs; 433 1.1 uch struct v7fs_node *v7fs_node; 434 1.1 uch struct v7fs_inode inode; 435 1.12 hannken v7fs_ino_t number; 436 1.1 uch int error; 437 1.1 uch 438 1.12 hannken KASSERT(key_len == sizeof(number)); 439 1.12 hannken memcpy(&number, key, key_len); 440 1.12 hannken 441 1.12 hannken v7fsmount = mp->mnt_data; 442 1.12 hannken fs = v7fsmount->core; 443 1.12 hannken 444 1.1 uch /* Lookup requested i-node */ 445 1.12 hannken if ((error = v7fs_inode_load(fs, &inode, number))) { 446 1.1 uch DPRINTF("v7fs_inode_load failed.\n"); 447 1.1 uch return error; 448 1.1 uch } 449 1.1 uch 450 1.12 hannken v7fs_node = pool_get(&v7fs_node_pool, PR_WAITOK); 451 1.12 hannken memset(v7fs_node, 0, sizeof(*v7fs_node)); 452 1.1 uch 453 1.12 hannken vp->v_tag = VT_V7FS; 454 1.12 hannken vp->v_data = v7fs_node; 455 1.1 uch v7fs_node->vnode = vp; 456 1.1 uch v7fs_node->v7fsmount = v7fsmount; 457 1.1 uch v7fs_node->inode = inode;/*structure copy */ 458 1.1 uch v7fs_node->lockf = NULL; /* advlock */ 459 1.1 uch 460 1.1 uch genfs_node_init(vp, &v7fs_genfsops); 461 1.1 uch uvm_vnp_setsize(vp, v7fs_inode_filesize(&inode)); 462 1.1 uch 463 1.12 hannken if (number == V7FS_ROOT_INODE) { 464 1.1 uch vp->v_type = VDIR; 465 1.1 uch vp->v_vflag |= VV_ROOT; 466 1.12 hannken vp->v_op = v7fs_vnodeop_p; 467 1.1 uch } else { 468 1.1 uch vp->v_type = v7fs_mode_to_vtype(inode.mode); 469 1.1 uch 470 1.1 uch if (vp->v_type == VBLK || vp->v_type == VCHR) { 471 1.1 uch dev_t rdev = inode.device; 472 1.1 uch vp->v_op = v7fs_specop_p; 473 1.1 uch spec_node_init(vp, rdev); 474 1.1 uch } else if (vp->v_type == VFIFO) { 475 1.1 uch vp->v_op = v7fs_fifoop_p; 476 1.12 hannken } else { 477 1.12 hannken vp->v_op = v7fs_vnodeop_p; 478 1.1 uch } 479 1.1 uch } 480 1.1 uch 481 1.12 hannken *new_key = &v7fs_node->inode.inode_number; 482 1.12 hannken 483 1.12 hannken return 0; 484 1.12 hannken } 485 1.12 hannken 486 1.12 hannken 487 1.12 hannken int 488 1.17 ad v7fs_vget(struct mount *mp, ino_t ino, int lktype, struct vnode **vpp) 489 1.12 hannken { 490 1.12 hannken int error; 491 1.12 hannken v7fs_ino_t number; 492 1.12 hannken struct vnode *vp; 493 1.12 hannken 494 1.12 hannken KASSERT(ino <= UINT16_MAX); 495 1.12 hannken number = ino; 496 1.12 hannken 497 1.12 hannken error = vcache_get(mp, &number, sizeof(number), &vp); 498 1.12 hannken if (error) 499 1.12 hannken return error; 500 1.17 ad error = vn_lock(vp, lktype); 501 1.12 hannken if (error) { 502 1.12 hannken vrele(vp); 503 1.12 hannken return error; 504 1.12 hannken } 505 1.12 hannken 506 1.1 uch *vpp = vp; 507 1.1 uch 508 1.1 uch return 0; 509 1.1 uch } 510 1.1 uch 511 1.1 uch int 512 1.17 ad v7fs_fhtovp(struct mount *mp, struct fid *fid, int lktype, struct vnode **vpp) 513 1.1 uch { 514 1.1 uch 515 1.1 uch DPRINTF("\n"); 516 1.1 uch /* notyet */ 517 1.1 uch return EOPNOTSUPP; 518 1.1 uch } 519 1.1 uch 520 1.1 uch int 521 1.1 uch v7fs_vptofh(struct vnode *vpp, struct fid *fid, size_t *fh_size) 522 1.1 uch { 523 1.1 uch 524 1.1 uch DPRINTF("\n"); 525 1.1 uch /* notyet */ 526 1.1 uch return EOPNOTSUPP; 527 1.1 uch } 528 1.1 uch 529 1.1 uch void 530 1.1 uch v7fs_init(void) 531 1.1 uch { 532 1.1 uch 533 1.1 uch DPRINTF("\n"); 534 1.1 uch pool_init(&v7fs_node_pool, sizeof(struct v7fs_node), 0, 0, 0, 535 1.1 uch "v7fs_node_pool", &pool_allocator_nointr, IPL_NONE); 536 1.1 uch } 537 1.1 uch 538 1.1 uch void 539 1.1 uch v7fs_reinit(void) 540 1.1 uch { 541 1.1 uch 542 1.1 uch /* Nothing to do. */ 543 1.1 uch DPRINTF("\n"); 544 1.1 uch } 545 1.1 uch 546 1.1 uch void 547 1.1 uch v7fs_done(void) 548 1.1 uch { 549 1.1 uch 550 1.1 uch DPRINTF("\n"); 551 1.1 uch pool_destroy(&v7fs_node_pool); 552 1.1 uch } 553 1.1 uch 554 1.1 uch int 555 1.1 uch v7fs_gop_alloc(struct vnode *vp, off_t off, off_t len, int flags, 556 1.1 uch kauth_cred_t cred) 557 1.1 uch { 558 1.1 uch 559 1.1 uch DPRINTF("\n"); 560 1.1 uch return 0; 561 1.1 uch } 562 1.1 uch 563 1.1 uch int 564 1.1 uch v7fs_mountroot(void) 565 1.1 uch { 566 1.1 uch struct mount *mp; 567 1.1 uch int error; 568 1.1 uch 569 1.1 uch DPRINTF(""); 570 1.1 uch /* On mountroot, devvp (rootdev) is opened by vfs_mountroot */ 571 1.2 uch if ((error = is_v7fs_partition (rootvp))) 572 1.2 uch return error; 573 1.1 uch 574 1.1 uch if ((error = vfs_rootmountalloc(MOUNT_V7FS, "root_device", &mp))) { 575 1.1 uch DPRINTF("mountalloc error=%d\n", error); 576 1.1 uch vrele(rootvp); 577 1.1 uch return error; 578 1.1 uch } 579 1.1 uch 580 1.1 uch if ((error = v7fs_mountfs(rootvp, mp, _BYTE_ORDER))) { 581 1.1 uch DPRINTF("mountfs error=%d\n", error); 582 1.15 hannken vfs_unbusy(mp); 583 1.14 hannken vfs_rele(mp); 584 1.1 uch return error; 585 1.1 uch } 586 1.1 uch 587 1.9 christos mountlist_append(mp); 588 1.1 uch 589 1.15 hannken vfs_unbusy(mp); 590 1.1 uch 591 1.1 uch return 0; 592 1.1 uch } 593