1*060d2ed9Sahoka /* $NetBSD: chfs_vfsops.c,v 1.1 2011/11/24 15:51:32 ahoka Exp $ */ 2*060d2ed9Sahoka 3*060d2ed9Sahoka /*- 4*060d2ed9Sahoka * Copyright (c) 2010 Department of Software Engineering, 5*060d2ed9Sahoka * University of Szeged, Hungary 6*060d2ed9Sahoka * Copyright (C) 2010 Tamas Toth <ttoth@inf.u-szeged.hu> 7*060d2ed9Sahoka * Copyright (C) 2010 Adam Hoka <ahoka@NetBSD.org> 8*060d2ed9Sahoka * All rights reserved. 9*060d2ed9Sahoka * 10*060d2ed9Sahoka * This code is derived from software contributed to The NetBSD Foundation 11*060d2ed9Sahoka * by the Department of Software Engineering, University of Szeged, Hungary 12*060d2ed9Sahoka * 13*060d2ed9Sahoka * Redistribution and use in source and binary forms, with or without 14*060d2ed9Sahoka * modification, are permitted provided that the following conditions 15*060d2ed9Sahoka * are met: 16*060d2ed9Sahoka * 1. Redistributions of source code must retain the above copyright 17*060d2ed9Sahoka * notice, this list of conditions and the following disclaimer. 18*060d2ed9Sahoka * 2. Redistributions in binary form must reproduce the above copyright 19*060d2ed9Sahoka * notice, this list of conditions and the following disclaimer in the 20*060d2ed9Sahoka * documentation and/or other materials provided with the distribution. 21*060d2ed9Sahoka * 22*060d2ed9Sahoka * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 23*060d2ed9Sahoka * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 24*060d2ed9Sahoka * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 25*060d2ed9Sahoka * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 26*060d2ed9Sahoka * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 27*060d2ed9Sahoka * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 28*060d2ed9Sahoka * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED 29*060d2ed9Sahoka * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 30*060d2ed9Sahoka * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 31*060d2ed9Sahoka * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 32*060d2ed9Sahoka * SUCH DAMAGE. 33*060d2ed9Sahoka */ 34*060d2ed9Sahoka 35*060d2ed9Sahoka #include <sys/cdefs.h> 36*060d2ed9Sahoka 37*060d2ed9Sahoka #include <sys/param.h> 38*060d2ed9Sahoka #include <sys/types.h> 39*060d2ed9Sahoka #include <sys/kmem.h> 40*060d2ed9Sahoka #include <sys/mount.h> 41*060d2ed9Sahoka #include <sys/stat.h> 42*060d2ed9Sahoka #include <sys/systm.h> 43*060d2ed9Sahoka #include <sys/proc.h> 44*060d2ed9Sahoka #include <sys/module.h> 45*060d2ed9Sahoka #include <sys/namei.h> 46*060d2ed9Sahoka #include <sys/malloc.h> 47*060d2ed9Sahoka #include <sys/fcntl.h> 48*060d2ed9Sahoka #include <sys/conf.h> 49*060d2ed9Sahoka #include <sys/buf.h> 50*060d2ed9Sahoka //XXX needed just for debugging 51*060d2ed9Sahoka #include <sys/fstrans.h> 52*060d2ed9Sahoka #include <sys/sleepq.h> 53*060d2ed9Sahoka #include <sys/lockdebug.h> 54*060d2ed9Sahoka #include <sys/ktrace.h> 55*060d2ed9Sahoka 56*060d2ed9Sahoka #include <uvm/uvm.h> 57*060d2ed9Sahoka #include <uvm/uvm_pager.h> 58*060d2ed9Sahoka #include <ufs/ufs/dir.h> 59*060d2ed9Sahoka //#include <ufs/ufs/inode.h> 60*060d2ed9Sahoka #include <ufs/ufs/ufs_extern.h> 61*060d2ed9Sahoka #include <miscfs/genfs/genfs.h> 62*060d2ed9Sahoka #include <miscfs/genfs/genfs_node.h> 63*060d2ed9Sahoka #include <miscfs/specfs/specdev.h> 64*060d2ed9Sahoka //#include </root/xipffs/netbsd.chfs/chfs.h> 65*060d2ed9Sahoka //#include </root/xipffs/netbsd.chfs/chfs_args.h> 66*060d2ed9Sahoka #include "chfs.h" 67*060d2ed9Sahoka #include "chfs_args.h" 68*060d2ed9Sahoka 69*060d2ed9Sahoka MODULE(MODULE_CLASS_VFS, chfs, "flash"); 70*060d2ed9Sahoka 71*060d2ed9Sahoka /* --------------------------------------------------------------------- */ 72*060d2ed9Sahoka /* functions */ 73*060d2ed9Sahoka 74*060d2ed9Sahoka static int chfs_mount(struct mount *, const char *, void *, size_t *); 75*060d2ed9Sahoka static int chfs_unmount(struct mount *, int); 76*060d2ed9Sahoka static int chfs_root(struct mount *, struct vnode **); 77*060d2ed9Sahoka static int chfs_vget(struct mount *, ino_t, struct vnode **); 78*060d2ed9Sahoka static int chfs_fhtovp(struct mount *, struct fid *, struct vnode **); 79*060d2ed9Sahoka static int chfs_vptofh(struct vnode *, struct fid *, size_t *); 80*060d2ed9Sahoka static int chfs_start(struct mount *, int); 81*060d2ed9Sahoka static int chfs_statvfs(struct mount *, struct statvfs *); 82*060d2ed9Sahoka static int chfs_sync(struct mount *, int, kauth_cred_t); 83*060d2ed9Sahoka static void chfs_init(void); 84*060d2ed9Sahoka static void chfs_reinit(void); 85*060d2ed9Sahoka static void chfs_done(void); 86*060d2ed9Sahoka static int chfs_snapshot(struct mount *, struct vnode *, 87*060d2ed9Sahoka struct timespec *); 88*060d2ed9Sahoka 89*060d2ed9Sahoka /* --------------------------------------------------------------------- */ 90*060d2ed9Sahoka /* structures */ 91*060d2ed9Sahoka 92*060d2ed9Sahoka int 93*060d2ed9Sahoka chfs_gop_alloc(struct vnode *vp, off_t off, off_t len, int flags, 94*060d2ed9Sahoka kauth_cred_t cred) 95*060d2ed9Sahoka { 96*060d2ed9Sahoka return (0); 97*060d2ed9Sahoka } 98*060d2ed9Sahoka 99*060d2ed9Sahoka const struct genfs_ops chfs_genfsops = { 100*060d2ed9Sahoka .gop_size = genfs_size, 101*060d2ed9Sahoka .gop_alloc = chfs_gop_alloc, 102*060d2ed9Sahoka .gop_write = genfs_gop_write, 103*060d2ed9Sahoka .gop_markupdate = ufs_gop_markupdate, 104*060d2ed9Sahoka }; 105*060d2ed9Sahoka 106*060d2ed9Sahoka /* 107*060d2ed9Sahoka static const struct ufs_ops chfs_ufsops = { 108*060d2ed9Sahoka .uo_itimes = chfs_itimes, 109*060d2ed9Sahoka .uo_update = chfs_update, 110*060d2ed9Sahoka }; 111*060d2ed9Sahoka */ 112*060d2ed9Sahoka 113*060d2ed9Sahoka struct pool chfs_inode_pool; 114*060d2ed9Sahoka 115*060d2ed9Sahoka /* for looking up the major for flash */ 116*060d2ed9Sahoka extern const struct cdevsw flash_cdevsw; 117*060d2ed9Sahoka 118*060d2ed9Sahoka /* --------------------------------------------------------------------- */ 119*060d2ed9Sahoka 120*060d2ed9Sahoka static int 121*060d2ed9Sahoka chfs_mount(struct mount *mp, 122*060d2ed9Sahoka const char *path, void *data, size_t *data_len) 123*060d2ed9Sahoka { 124*060d2ed9Sahoka struct lwp *l = curlwp; 125*060d2ed9Sahoka struct nameidata nd; 126*060d2ed9Sahoka struct pathbuf *pb; 127*060d2ed9Sahoka struct vnode *devvp = NULL; 128*060d2ed9Sahoka struct ufs_args *args = data; 129*060d2ed9Sahoka struct ufsmount *ump = NULL; 130*060d2ed9Sahoka struct chfs_mount *chmp; 131*060d2ed9Sahoka int err = 0; 132*060d2ed9Sahoka int xflags; 133*060d2ed9Sahoka 134*060d2ed9Sahoka dbg("mount()\n"); 135*060d2ed9Sahoka 136*060d2ed9Sahoka if (*data_len < sizeof *args) 137*060d2ed9Sahoka return EINVAL; 138*060d2ed9Sahoka 139*060d2ed9Sahoka if (mp->mnt_flag & MNT_GETARGS) { 140*060d2ed9Sahoka ump = VFSTOUFS(mp); 141*060d2ed9Sahoka if (ump == NULL) 142*060d2ed9Sahoka return EIO; 143*060d2ed9Sahoka memset(args, 0, sizeof *args); 144*060d2ed9Sahoka args->fspec = NULL; 145*060d2ed9Sahoka *data_len = sizeof *args; 146*060d2ed9Sahoka return 0; 147*060d2ed9Sahoka } 148*060d2ed9Sahoka 149*060d2ed9Sahoka if (mp->mnt_flag & MNT_UPDATE) { 150*060d2ed9Sahoka /* XXX: There is no support yet to update file system 151*060d2ed9Sahoka * settings. Should be added. */ 152*060d2ed9Sahoka 153*060d2ed9Sahoka return ENODEV; 154*060d2ed9Sahoka } 155*060d2ed9Sahoka 156*060d2ed9Sahoka if (args->fspec != NULL) { 157*060d2ed9Sahoka err = pathbuf_copyin(args->fspec, &pb); 158*060d2ed9Sahoka if (err) { 159*060d2ed9Sahoka return err; 160*060d2ed9Sahoka } 161*060d2ed9Sahoka /* 162*060d2ed9Sahoka * Look up the name and verify that it's sane. 163*060d2ed9Sahoka */ 164*060d2ed9Sahoka NDINIT(&nd, LOOKUP, FOLLOW, pb); 165*060d2ed9Sahoka if ((err = namei(&nd)) != 0 ) 166*060d2ed9Sahoka return (err); 167*060d2ed9Sahoka devvp = nd.ni_vp; 168*060d2ed9Sahoka 169*060d2ed9Sahoka /* 170*060d2ed9Sahoka * Be sure this is a valid block device 171*060d2ed9Sahoka */ 172*060d2ed9Sahoka if (devvp->v_type != VBLK) 173*060d2ed9Sahoka err = ENOTBLK; 174*060d2ed9Sahoka else if (bdevsw_lookup(devvp->v_rdev) == NULL) 175*060d2ed9Sahoka err = ENXIO; 176*060d2ed9Sahoka } 177*060d2ed9Sahoka 178*060d2ed9Sahoka if (err) { 179*060d2ed9Sahoka vrele(devvp); 180*060d2ed9Sahoka return (err); 181*060d2ed9Sahoka } 182*060d2ed9Sahoka 183*060d2ed9Sahoka if (mp->mnt_flag & MNT_RDONLY) 184*060d2ed9Sahoka xflags = FREAD; 185*060d2ed9Sahoka else 186*060d2ed9Sahoka xflags = FREAD|FWRITE; 187*060d2ed9Sahoka 188*060d2ed9Sahoka err = VOP_OPEN(devvp, xflags, FSCRED); 189*060d2ed9Sahoka if (err) 190*060d2ed9Sahoka goto fail; 191*060d2ed9Sahoka 192*060d2ed9Sahoka 193*060d2ed9Sahoka err = chfs_mountfs(devvp, mp); 194*060d2ed9Sahoka if (err) { 195*060d2ed9Sahoka vn_lock(devvp, LK_EXCLUSIVE | LK_RETRY); 196*060d2ed9Sahoka (void)VOP_CLOSE(devvp, xflags, NOCRED); 197*060d2ed9Sahoka VOP_UNLOCK(devvp); 198*060d2ed9Sahoka goto fail; 199*060d2ed9Sahoka } 200*060d2ed9Sahoka ump = VFSTOUFS(mp); 201*060d2ed9Sahoka chmp = ump->um_chfs; 202*060d2ed9Sahoka 203*060d2ed9Sahoka vfs_getnewfsid(mp); 204*060d2ed9Sahoka chmp->chm_fsmp = mp; 205*060d2ed9Sahoka 206*060d2ed9Sahoka return set_statvfs_info(path, 207*060d2ed9Sahoka UIO_USERSPACE, args->fspec, 208*060d2ed9Sahoka UIO_USERSPACE, mp->mnt_op->vfs_name, mp, l); 209*060d2ed9Sahoka 210*060d2ed9Sahoka fail: 211*060d2ed9Sahoka vrele(devvp); 212*060d2ed9Sahoka return (err); 213*060d2ed9Sahoka } 214*060d2ed9Sahoka 215*060d2ed9Sahoka 216*060d2ed9Sahoka int 217*060d2ed9Sahoka chfs_mountfs(struct vnode *devvp, struct mount *mp) 218*060d2ed9Sahoka { 219*060d2ed9Sahoka struct lwp *l = curlwp; 220*060d2ed9Sahoka struct proc *p; 221*060d2ed9Sahoka kauth_cred_t cred; 222*060d2ed9Sahoka devmajor_t flash_major; 223*060d2ed9Sahoka dev_t dev; 224*060d2ed9Sahoka struct ufsmount* ump = NULL; 225*060d2ed9Sahoka struct chfs_mount* chmp; 226*060d2ed9Sahoka struct vnode *vp; 227*060d2ed9Sahoka int err = 0; 228*060d2ed9Sahoka 229*060d2ed9Sahoka dbg("mountfs()\n"); 230*060d2ed9Sahoka 231*060d2ed9Sahoka dev = devvp->v_rdev; 232*060d2ed9Sahoka p = l ? l->l_proc : NULL; 233*060d2ed9Sahoka cred = l ? l->l_cred : NOCRED; 234*060d2ed9Sahoka 235*060d2ed9Sahoka /* Flush out any old buffers remaining from a previous use. */ 236*060d2ed9Sahoka vn_lock(devvp, LK_EXCLUSIVE | LK_RETRY); 237*060d2ed9Sahoka err = vinvalbuf(devvp, V_SAVE, cred, l, 0, 0); 238*060d2ed9Sahoka VOP_UNLOCK(devvp); 239*060d2ed9Sahoka if (err) 240*060d2ed9Sahoka return (err); 241*060d2ed9Sahoka 242*060d2ed9Sahoka flash_major = cdevsw_lookup_major(&flash_cdevsw); 243*060d2ed9Sahoka 244*060d2ed9Sahoka if (devvp->v_type != VBLK) 245*060d2ed9Sahoka err = ENOTBLK; 246*060d2ed9Sahoka else if (bdevsw_lookup(dev) == NULL) 247*060d2ed9Sahoka err = ENXIO; 248*060d2ed9Sahoka else if (major(dev) != flash_major) { 249*060d2ed9Sahoka dbg("major(dev): %d, flash_major: %d\n", 250*060d2ed9Sahoka major(dev), flash_major); 251*060d2ed9Sahoka err = ENODEV; 252*060d2ed9Sahoka } 253*060d2ed9Sahoka if (err) { 254*060d2ed9Sahoka vrele(devvp); 255*060d2ed9Sahoka return (err); 256*060d2ed9Sahoka } 257*060d2ed9Sahoka 258*060d2ed9Sahoka ump = malloc(sizeof(*ump), M_UFSMNT, M_WAITOK); 259*060d2ed9Sahoka memset(ump, 0, sizeof(*ump)); 260*060d2ed9Sahoka ump->um_fstype = UFS1; 261*060d2ed9Sahoka //ump->um_ops = &chfs_ufsops; 262*060d2ed9Sahoka ump->um_chfs = malloc(sizeof(struct chfs_mount), 263*060d2ed9Sahoka M_UFSMNT, M_WAITOK); 264*060d2ed9Sahoka memset(ump->um_chfs, 0, sizeof(struct chfs_mount)); 265*060d2ed9Sahoka 266*060d2ed9Sahoka mutex_init(&ump->um_lock, MUTEX_DEFAULT, IPL_NONE); 267*060d2ed9Sahoka 268*060d2ed9Sahoka /* Get superblock and set flash device number */ 269*060d2ed9Sahoka chmp = ump->um_chfs; 270*060d2ed9Sahoka if (!chmp) 271*060d2ed9Sahoka return ENOMEM; 272*060d2ed9Sahoka 273*060d2ed9Sahoka chmp->chm_ebh = kmem_alloc(sizeof(struct chfs_ebh), KM_SLEEP); 274*060d2ed9Sahoka 275*060d2ed9Sahoka dbg("[]opening flash: %u\n", (unsigned int)devvp->v_rdev); 276*060d2ed9Sahoka err = ebh_open(chmp->chm_ebh, devvp->v_rdev); 277*060d2ed9Sahoka if (err) { 278*060d2ed9Sahoka dbg("error while opening flash\n"); 279*060d2ed9Sahoka kmem_free(chmp->chm_ebh, sizeof(struct chfs_ebh)); 280*060d2ed9Sahoka free(chmp, M_UFSMNT); 281*060d2ed9Sahoka return err; 282*060d2ed9Sahoka } 283*060d2ed9Sahoka 284*060d2ed9Sahoka //TODO check flash sizes 285*060d2ed9Sahoka 286*060d2ed9Sahoka chmp->chm_gbl_version = 0; 287*060d2ed9Sahoka chmp->chm_vnocache_hash = chfs_vnocache_hash_init(); 288*060d2ed9Sahoka 289*060d2ed9Sahoka chmp->chm_blocks = kmem_zalloc(chmp->chm_ebh->peb_nr * 290*060d2ed9Sahoka sizeof(struct chfs_eraseblock), KM_SLEEP); 291*060d2ed9Sahoka 292*060d2ed9Sahoka if (!chmp->chm_blocks) { 293*060d2ed9Sahoka kmem_free(chmp->chm_ebh, chmp->chm_ebh->peb_nr * 294*060d2ed9Sahoka sizeof(struct chfs_eraseblock)); 295*060d2ed9Sahoka ebh_close(chmp->chm_ebh); 296*060d2ed9Sahoka free(chmp, M_UFSMNT); 297*060d2ed9Sahoka return ENOMEM; 298*060d2ed9Sahoka } 299*060d2ed9Sahoka 300*060d2ed9Sahoka mutex_init(&chmp->chm_lock_mountfields, MUTEX_DEFAULT, IPL_NONE); 301*060d2ed9Sahoka mutex_init(&chmp->chm_lock_sizes, MUTEX_DEFAULT, IPL_NONE); 302*060d2ed9Sahoka mutex_init(&chmp->chm_lock_vnocache, MUTEX_DEFAULT, IPL_NONE); 303*060d2ed9Sahoka 304*060d2ed9Sahoka //XXX 305*060d2ed9Sahoka chmp->chm_fs_bmask = -4096; 306*060d2ed9Sahoka chmp->chm_fs_bsize = 4096; 307*060d2ed9Sahoka chmp->chm_fs_qbmask = 4095; 308*060d2ed9Sahoka chmp->chm_fs_bshift = 12; 309*060d2ed9Sahoka chmp->chm_fs_fmask = -2048; 310*060d2ed9Sahoka chmp->chm_fs_qfmask = 2047; 311*060d2ed9Sahoka 312*060d2ed9Sahoka chmp->chm_wbuf_pagesize = chmp->chm_ebh->flash_if->page_size; 313*060d2ed9Sahoka dbg("wbuf size: %zu\n", chmp->chm_wbuf_pagesize); 314*060d2ed9Sahoka chmp->chm_wbuf = kmem_alloc(chmp->chm_wbuf_pagesize, KM_SLEEP); 315*060d2ed9Sahoka rw_init(&chmp->chm_lock_wbuf); 316*060d2ed9Sahoka 317*060d2ed9Sahoka //init queues 318*060d2ed9Sahoka TAILQ_INIT(&chmp->chm_free_queue); 319*060d2ed9Sahoka TAILQ_INIT(&chmp->chm_clean_queue); 320*060d2ed9Sahoka TAILQ_INIT(&chmp->chm_dirty_queue); 321*060d2ed9Sahoka TAILQ_INIT(&chmp->chm_very_dirty_queue); 322*060d2ed9Sahoka TAILQ_INIT(&chmp->chm_erasable_pending_wbuf_queue); 323*060d2ed9Sahoka TAILQ_INIT(&chmp->chm_erase_pending_queue); 324*060d2ed9Sahoka 325*060d2ed9Sahoka chfs_calc_trigger_levels(chmp); 326*060d2ed9Sahoka 327*060d2ed9Sahoka chmp->chm_nr_free_blocks = 0; 328*060d2ed9Sahoka chmp->chm_nr_erasable_blocks = 0; 329*060d2ed9Sahoka chmp->chm_max_vno = 2; 330*060d2ed9Sahoka chmp->chm_checked_vno = 2; 331*060d2ed9Sahoka chmp->chm_unchecked_size = 0; 332*060d2ed9Sahoka chmp->chm_used_size = 0; 333*060d2ed9Sahoka chmp->chm_dirty_size = 0; 334*060d2ed9Sahoka chmp->chm_wasted_size = 0; 335*060d2ed9Sahoka chmp->chm_free_size = chmp->chm_ebh->eb_size * chmp->chm_ebh->peb_nr; 336*060d2ed9Sahoka err = chfs_build_filesystem(chmp); 337*060d2ed9Sahoka 338*060d2ed9Sahoka if (err) { 339*060d2ed9Sahoka chfs_vnocache_hash_destroy(chmp->chm_vnocache_hash); 340*060d2ed9Sahoka kmem_free(chmp->chm_ebh, chmp->chm_ebh->peb_nr * 341*060d2ed9Sahoka sizeof(struct chfs_eraseblock)); 342*060d2ed9Sahoka ebh_close(chmp->chm_ebh); 343*060d2ed9Sahoka free(chmp, M_UFSMNT); 344*060d2ed9Sahoka return EIO; 345*060d2ed9Sahoka } 346*060d2ed9Sahoka 347*060d2ed9Sahoka mp->mnt_data = ump; 348*060d2ed9Sahoka mp->mnt_stat.f_fsidx.__fsid_val[0] = (long)dev; 349*060d2ed9Sahoka mp->mnt_stat.f_fsidx.__fsid_val[1] = makefstype(MOUNT_CHFS); 350*060d2ed9Sahoka mp->mnt_stat.f_fsid = mp->mnt_stat.f_fsidx.__fsid_val[0]; 351*060d2ed9Sahoka mp->mnt_stat.f_namemax = MAXNAMLEN; 352*060d2ed9Sahoka mp->mnt_flag |= MNT_LOCAL; 353*060d2ed9Sahoka mp->mnt_fs_bshift = PAGE_SHIFT; 354*060d2ed9Sahoka mp->mnt_dev_bshift = DEV_BSHIFT; 355*060d2ed9Sahoka mp->mnt_iflag |= IMNT_MPSAFE; 356*060d2ed9Sahoka ump->um_flags = 0; 357*060d2ed9Sahoka ump->um_mountp = mp; 358*060d2ed9Sahoka ump->um_dev = dev; 359*060d2ed9Sahoka ump->um_devvp = devvp; 360*060d2ed9Sahoka ump->um_maxfilesize = 1048512 * 1024; 361*060d2ed9Sahoka /*TODO fill these fields 362*060d2ed9Sahoka ump->um_nindir = 363*060d2ed9Sahoka ump->um_lognindir = 364*060d2ed9Sahoka ump->um_bptrtodb = 365*060d2ed9Sahoka ump->um_seqinc = 366*060d2ed9Sahoka ump->um_maxsymlinklen = 367*060d2ed9Sahoka ump->um_dirblksiz = 368*060d2ed9Sahoka ump->um_maxfilesize = 369*060d2ed9Sahoka */ 370*060d2ed9Sahoka 371*060d2ed9Sahoka /* 372*060d2ed9Sahoka * Allocate the root vnode. 373*060d2ed9Sahoka */ 374*060d2ed9Sahoka err = VFS_VGET(mp, CHFS_ROOTINO, &vp); 375*060d2ed9Sahoka if (err) { 376*060d2ed9Sahoka dbg("error: %d while allocating root node\n", err); 377*060d2ed9Sahoka return err; 378*060d2ed9Sahoka } 379*060d2ed9Sahoka vput(vp); 380*060d2ed9Sahoka 381*060d2ed9Sahoka chfs_gc_thread_start(chmp); 382*060d2ed9Sahoka mutex_enter(&chmp->chm_lock_mountfields); 383*060d2ed9Sahoka chfs_gc_trigger(chmp); 384*060d2ed9Sahoka mutex_exit(&chmp->chm_lock_mountfields); 385*060d2ed9Sahoka 386*060d2ed9Sahoka devvp->v_specmountpoint = mp; 387*060d2ed9Sahoka return 0; 388*060d2ed9Sahoka } 389*060d2ed9Sahoka 390*060d2ed9Sahoka /* --------------------------------------------------------------------- */ 391*060d2ed9Sahoka 392*060d2ed9Sahoka /* ARGSUSED2 */ 393*060d2ed9Sahoka static int 394*060d2ed9Sahoka chfs_unmount(struct mount *mp, int mntflags) 395*060d2ed9Sahoka { 396*060d2ed9Sahoka int flags = 0, i = 0; 397*060d2ed9Sahoka struct ufsmount *ump; 398*060d2ed9Sahoka struct chfs_mount *chmp; 399*060d2ed9Sahoka // struct chfs_vnode_cache *vc, *next; 400*060d2ed9Sahoka 401*060d2ed9Sahoka if (mntflags & MNT_FORCE) 402*060d2ed9Sahoka flags |= FORCECLOSE; 403*060d2ed9Sahoka 404*060d2ed9Sahoka dbg("[START]\n"); 405*060d2ed9Sahoka 406*060d2ed9Sahoka ump = VFSTOUFS(mp); 407*060d2ed9Sahoka chmp = ump->um_chfs; 408*060d2ed9Sahoka 409*060d2ed9Sahoka chfs_gc_thread_stop(chmp); 410*060d2ed9Sahoka 411*060d2ed9Sahoka (void)vflush(mp, NULLVP, flags); 412*060d2ed9Sahoka 413*060d2ed9Sahoka if (chmp->chm_wbuf_len) { 414*060d2ed9Sahoka mutex_enter(&chmp->chm_lock_mountfields); 415*060d2ed9Sahoka chfs_flush_pending_wbuf(chmp); 416*060d2ed9Sahoka mutex_exit(&chmp->chm_lock_mountfields); 417*060d2ed9Sahoka } 418*060d2ed9Sahoka 419*060d2ed9Sahoka for (i = 0; i < chmp->chm_ebh->peb_nr; i++) { 420*060d2ed9Sahoka chfs_free_node_refs(&chmp->chm_blocks[i]); 421*060d2ed9Sahoka } 422*060d2ed9Sahoka 423*060d2ed9Sahoka chfs_vnocache_hash_destroy(chmp->chm_vnocache_hash); 424*060d2ed9Sahoka 425*060d2ed9Sahoka ebh_close(chmp->chm_ebh); 426*060d2ed9Sahoka 427*060d2ed9Sahoka rw_destroy(&chmp->chm_lock_wbuf); 428*060d2ed9Sahoka mutex_destroy(&chmp->chm_lock_vnocache); 429*060d2ed9Sahoka mutex_destroy(&chmp->chm_lock_sizes); 430*060d2ed9Sahoka mutex_destroy(&chmp->chm_lock_mountfields); 431*060d2ed9Sahoka 432*060d2ed9Sahoka if (ump->um_devvp->v_type != VBAD) { 433*060d2ed9Sahoka ump->um_devvp->v_specmountpoint = NULL; 434*060d2ed9Sahoka } 435*060d2ed9Sahoka vn_lock(ump->um_devvp, LK_EXCLUSIVE | LK_RETRY); 436*060d2ed9Sahoka (void)VOP_CLOSE(ump->um_devvp, FREAD|FWRITE, NOCRED); 437*060d2ed9Sahoka vput(ump->um_devvp); 438*060d2ed9Sahoka 439*060d2ed9Sahoka mutex_destroy(&ump->um_lock); 440*060d2ed9Sahoka 441*060d2ed9Sahoka //free(ump->um_chfs, M_UFSMNT); 442*060d2ed9Sahoka free(ump, M_UFSMNT); 443*060d2ed9Sahoka mp->mnt_data = NULL; 444*060d2ed9Sahoka mp->mnt_flag &= ~MNT_LOCAL; 445*060d2ed9Sahoka dbg("[END]\n"); 446*060d2ed9Sahoka return (0); 447*060d2ed9Sahoka } 448*060d2ed9Sahoka 449*060d2ed9Sahoka /* --------------------------------------------------------------------- */ 450*060d2ed9Sahoka 451*060d2ed9Sahoka static int 452*060d2ed9Sahoka chfs_root(struct mount *mp, struct vnode **vpp) 453*060d2ed9Sahoka { 454*060d2ed9Sahoka struct vnode *vp; 455*060d2ed9Sahoka int error; 456*060d2ed9Sahoka 457*060d2ed9Sahoka if ((error = VFS_VGET(mp, (ino_t)ROOTINO, &vp)) != 0) 458*060d2ed9Sahoka return error; 459*060d2ed9Sahoka *vpp = vp; 460*060d2ed9Sahoka return 0; 461*060d2ed9Sahoka } 462*060d2ed9Sahoka 463*060d2ed9Sahoka /* --------------------------------------------------------------------- */ 464*060d2ed9Sahoka 465*060d2ed9Sahoka extern rb_tree_ops_t frag_rbtree_ops; 466*060d2ed9Sahoka 467*060d2ed9Sahoka static int 468*060d2ed9Sahoka chfs_vget(struct mount *mp, ino_t ino, struct vnode **vpp) 469*060d2ed9Sahoka { 470*060d2ed9Sahoka struct chfs_mount *chmp; 471*060d2ed9Sahoka struct chfs_inode *ip; 472*060d2ed9Sahoka struct ufsmount *ump; 473*060d2ed9Sahoka struct vnode *vp; 474*060d2ed9Sahoka dev_t dev; 475*060d2ed9Sahoka int error; 476*060d2ed9Sahoka struct chfs_vnode_cache* chvc = NULL; 477*060d2ed9Sahoka struct chfs_node_ref* nref = NULL; 478*060d2ed9Sahoka struct buf *bp; 479*060d2ed9Sahoka 480*060d2ed9Sahoka dbg("vget() | ino: %llu\n", ino); 481*060d2ed9Sahoka 482*060d2ed9Sahoka ump = VFSTOUFS(mp); 483*060d2ed9Sahoka dev = ump->um_dev; 484*060d2ed9Sahoka retry: 485*060d2ed9Sahoka if (!vpp) { 486*060d2ed9Sahoka vpp = kmem_alloc(sizeof(struct vnode*), KM_SLEEP); 487*060d2ed9Sahoka } 488*060d2ed9Sahoka 489*060d2ed9Sahoka if ((*vpp = chfs_ihashget(dev, ino, LK_EXCLUSIVE)) != NULL) { 490*060d2ed9Sahoka return 0; 491*060d2ed9Sahoka } 492*060d2ed9Sahoka 493*060d2ed9Sahoka /* Allocate a new vnode/inode. */ 494*060d2ed9Sahoka if ((error = getnewvnode(VT_CHFS, 495*060d2ed9Sahoka mp, chfs_vnodeop_p, NULL, &vp)) != 0) { 496*060d2ed9Sahoka *vpp = NULL; 497*060d2ed9Sahoka return (error); 498*060d2ed9Sahoka } 499*060d2ed9Sahoka ip = pool_get(&chfs_inode_pool, PR_WAITOK); 500*060d2ed9Sahoka 501*060d2ed9Sahoka mutex_enter(&chfs_hashlock); 502*060d2ed9Sahoka if ((*vpp = chfs_ihashget(dev, ino, LK_EXCLUSIVE)) != NULL) { 503*060d2ed9Sahoka mutex_exit(&chfs_hashlock); 504*060d2ed9Sahoka ungetnewvnode(vp); 505*060d2ed9Sahoka pool_put(&chfs_inode_pool, ip); 506*060d2ed9Sahoka goto retry; 507*060d2ed9Sahoka } 508*060d2ed9Sahoka 509*060d2ed9Sahoka vp->v_vflag |= VV_LOCKSWORK; 510*060d2ed9Sahoka 511*060d2ed9Sahoka memset(ip, 0, sizeof(*ip)); 512*060d2ed9Sahoka vp->v_data = ip; 513*060d2ed9Sahoka ip->vp = vp; 514*060d2ed9Sahoka ip->ump = ump; 515*060d2ed9Sahoka ip->chmp = chmp = ump->um_chfs; 516*060d2ed9Sahoka ip->dev = dev; 517*060d2ed9Sahoka ip->ino = ino; 518*060d2ed9Sahoka vp->v_mount = mp; 519*060d2ed9Sahoka genfs_node_init(vp, &chfs_genfsops); 520*060d2ed9Sahoka 521*060d2ed9Sahoka rb_tree_init(&ip->fragtree, &frag_rbtree_ops); 522*060d2ed9Sahoka //mutex_init(&ip->inode_lock, MUTEX_DEFAULT, IPL_NONE); 523*060d2ed9Sahoka 524*060d2ed9Sahoka chfs_ihashins(ip); 525*060d2ed9Sahoka mutex_exit(&chfs_hashlock); 526*060d2ed9Sahoka 527*060d2ed9Sahoka // set root inode 528*060d2ed9Sahoka if (ino == CHFS_ROOTINO) { 529*060d2ed9Sahoka dbg("SETROOT\n"); 530*060d2ed9Sahoka vp->v_vflag |= VV_ROOT; 531*060d2ed9Sahoka vp->v_type = VDIR; 532*060d2ed9Sahoka ip->mode = IFMT | IEXEC | IWRITE | IREAD; 533*060d2ed9Sahoka ip->iflag |= (IN_ACCESS | IN_CHANGE | IN_UPDATE); 534*060d2ed9Sahoka chfs_update(vp, NULL, NULL, UPDATE_WAIT); 535*060d2ed9Sahoka // ip->dents = NULL; XXXTAILQ 536*060d2ed9Sahoka TAILQ_INIT(&ip->dents); 537*060d2ed9Sahoka chfs_set_vnode_size(vp, 512); 538*060d2ed9Sahoka } 539*060d2ed9Sahoka 540*060d2ed9Sahoka // set vnode cache 541*060d2ed9Sahoka mutex_enter(&chmp->chm_lock_vnocache); 542*060d2ed9Sahoka chvc = chfs_vnode_cache_get(chmp, ino); 543*060d2ed9Sahoka mutex_exit(&chmp->chm_lock_vnocache); 544*060d2ed9Sahoka if (!chvc) { 545*060d2ed9Sahoka dbg("!chvc\n"); 546*060d2ed9Sahoka /* XXX, we cant alloc under a lock, refactor this! */ 547*060d2ed9Sahoka chvc = chfs_vnode_cache_alloc(ino); 548*060d2ed9Sahoka mutex_enter(&chmp->chm_lock_vnocache); 549*060d2ed9Sahoka if (ino == CHFS_ROOTINO) { 550*060d2ed9Sahoka chvc->nlink = 2; 551*060d2ed9Sahoka chvc->pvno = CHFS_ROOTINO; 552*060d2ed9Sahoka chfs_vnode_cache_set_state(chmp, 553*060d2ed9Sahoka chvc, VNO_STATE_CHECKEDABSENT); 554*060d2ed9Sahoka } 555*060d2ed9Sahoka chfs_vnode_cache_add(chmp, chvc); 556*060d2ed9Sahoka mutex_exit(&chmp->chm_lock_vnocache); 557*060d2ed9Sahoka 558*060d2ed9Sahoka ip->chvc = chvc; 559*060d2ed9Sahoka TAILQ_INIT(&ip->dents); 560*060d2ed9Sahoka } else { 561*060d2ed9Sahoka dbg("chvc\n"); 562*060d2ed9Sahoka ip->chvc = chvc; 563*060d2ed9Sahoka // if we have a vnode cache, the node is already on flash, so read it 564*060d2ed9Sahoka if (ino == CHFS_ROOTINO) { 565*060d2ed9Sahoka chvc->pvno = CHFS_ROOTINO; 566*060d2ed9Sahoka TAILQ_INIT(&chvc->scan_dirents); 567*060d2ed9Sahoka } else { 568*060d2ed9Sahoka chfs_readvnode(mp, ino, &vp); 569*060d2ed9Sahoka } 570*060d2ed9Sahoka 571*060d2ed9Sahoka mutex_enter(&chmp->chm_lock_mountfields); 572*060d2ed9Sahoka // init type specific things 573*060d2ed9Sahoka switch (vp->v_type) { 574*060d2ed9Sahoka case VDIR: 575*060d2ed9Sahoka nref = chvc->dirents; 576*060d2ed9Sahoka while (nref && 577*060d2ed9Sahoka (struct chfs_vnode_cache *)nref != chvc) { 578*060d2ed9Sahoka chfs_readdirent(mp, nref, ip); 579*060d2ed9Sahoka nref = nref->nref_next; 580*060d2ed9Sahoka } 581*060d2ed9Sahoka chfs_set_vnode_size(vp, 512); 582*060d2ed9Sahoka break; 583*060d2ed9Sahoka case VREG: 584*060d2ed9Sahoka case VSOCK: 585*060d2ed9Sahoka //build the fragtree of the vnode 586*060d2ed9Sahoka dbg("read_inode_internal | ino: %llu\n", ip->ino); 587*060d2ed9Sahoka error = chfs_read_inode(chmp, ip); 588*060d2ed9Sahoka if (error) { 589*060d2ed9Sahoka vput(vp); 590*060d2ed9Sahoka *vpp = NULL; 591*060d2ed9Sahoka mutex_exit(&chmp->chm_lock_mountfields); 592*060d2ed9Sahoka return (error); 593*060d2ed9Sahoka } 594*060d2ed9Sahoka break; 595*060d2ed9Sahoka case VLNK: 596*060d2ed9Sahoka //build the fragtree of the vnode 597*060d2ed9Sahoka dbg("read_inode_internal | ino: %llu\n", ip->ino); 598*060d2ed9Sahoka error = chfs_read_inode_internal(chmp, ip); 599*060d2ed9Sahoka if (error) { 600*060d2ed9Sahoka vput(vp); 601*060d2ed9Sahoka *vpp = NULL; 602*060d2ed9Sahoka mutex_exit(&chmp->chm_lock_mountfields); 603*060d2ed9Sahoka return (error); 604*060d2ed9Sahoka } 605*060d2ed9Sahoka 606*060d2ed9Sahoka dbg("size: %llu\n", ip->size); 607*060d2ed9Sahoka bp = getiobuf(vp, true); 608*060d2ed9Sahoka bp->b_blkno = 0; 609*060d2ed9Sahoka bp->b_bufsize = bp->b_resid = 610*060d2ed9Sahoka bp->b_bcount = ip->size; 611*060d2ed9Sahoka bp->b_data = kmem_alloc(ip->size, KM_SLEEP); 612*060d2ed9Sahoka chfs_read_data(chmp, vp, bp); 613*060d2ed9Sahoka if (!ip->target) 614*060d2ed9Sahoka ip->target = kmem_alloc(ip->size, 615*060d2ed9Sahoka KM_SLEEP); 616*060d2ed9Sahoka memcpy(ip->target, bp->b_data, ip->size); 617*060d2ed9Sahoka kmem_free(bp->b_data, ip->size); 618*060d2ed9Sahoka putiobuf(bp); 619*060d2ed9Sahoka 620*060d2ed9Sahoka break; 621*060d2ed9Sahoka case VCHR: 622*060d2ed9Sahoka case VBLK: 623*060d2ed9Sahoka case VFIFO: 624*060d2ed9Sahoka //build the fragtree of the vnode 625*060d2ed9Sahoka dbg("read_inode_internal | ino: %llu\n", ip->ino); 626*060d2ed9Sahoka error = chfs_read_inode_internal(chmp, ip); 627*060d2ed9Sahoka if (error) { 628*060d2ed9Sahoka vput(vp); 629*060d2ed9Sahoka *vpp = NULL; 630*060d2ed9Sahoka mutex_exit(&chmp->chm_lock_mountfields); 631*060d2ed9Sahoka return (error); 632*060d2ed9Sahoka } 633*060d2ed9Sahoka 634*060d2ed9Sahoka bp = getiobuf(vp, true); 635*060d2ed9Sahoka bp->b_blkno = 0; 636*060d2ed9Sahoka bp->b_bufsize = bp->b_resid = 637*060d2ed9Sahoka bp->b_bcount = sizeof(dev_t); 638*060d2ed9Sahoka bp->b_data = kmem_alloc(sizeof(dev_t), KM_SLEEP); 639*060d2ed9Sahoka chfs_read_data(chmp, vp, bp); 640*060d2ed9Sahoka memcpy(&ip->rdev, 641*060d2ed9Sahoka bp->b_data, sizeof(dev_t)); 642*060d2ed9Sahoka kmem_free(bp->b_data, sizeof(dev_t)); 643*060d2ed9Sahoka putiobuf(bp); 644*060d2ed9Sahoka if (vp->v_type == VFIFO) 645*060d2ed9Sahoka vp->v_op = chfs_fifoop_p; 646*060d2ed9Sahoka else { 647*060d2ed9Sahoka vp->v_op = chfs_specop_p; 648*060d2ed9Sahoka spec_node_init(vp, ip->rdev); 649*060d2ed9Sahoka } 650*060d2ed9Sahoka 651*060d2ed9Sahoka break; 652*060d2ed9Sahoka case VNON: 653*060d2ed9Sahoka case VBAD: 654*060d2ed9Sahoka break; 655*060d2ed9Sahoka } 656*060d2ed9Sahoka mutex_exit(&chmp->chm_lock_mountfields); 657*060d2ed9Sahoka 658*060d2ed9Sahoka } 659*060d2ed9Sahoka 660*060d2ed9Sahoka /* finish inode initalization */ 661*060d2ed9Sahoka ip->devvp = ump->um_devvp; 662*060d2ed9Sahoka vref(ip->devvp); 663*060d2ed9Sahoka 664*060d2ed9Sahoka uvm_vnp_setsize(vp, ip->size); 665*060d2ed9Sahoka *vpp = vp; 666*060d2ed9Sahoka 667*060d2ed9Sahoka return 0; 668*060d2ed9Sahoka } 669*060d2ed9Sahoka 670*060d2ed9Sahoka /* --------------------------------------------------------------------- */ 671*060d2ed9Sahoka 672*060d2ed9Sahoka static int 673*060d2ed9Sahoka chfs_fhtovp(struct mount *mp, struct fid *fhp, struct vnode **vpp) 674*060d2ed9Sahoka { 675*060d2ed9Sahoka return ENODEV; 676*060d2ed9Sahoka } 677*060d2ed9Sahoka 678*060d2ed9Sahoka /* --------------------------------------------------------------------- */ 679*060d2ed9Sahoka 680*060d2ed9Sahoka static int 681*060d2ed9Sahoka chfs_vptofh(struct vnode *vp, struct fid *fhp, size_t *fh_size) 682*060d2ed9Sahoka { 683*060d2ed9Sahoka return ENODEV; 684*060d2ed9Sahoka } 685*060d2ed9Sahoka 686*060d2ed9Sahoka /* --------------------------------------------------------------------- */ 687*060d2ed9Sahoka 688*060d2ed9Sahoka static int 689*060d2ed9Sahoka chfs_start(struct mount *mp, int flags) 690*060d2ed9Sahoka { 691*060d2ed9Sahoka return 0; 692*060d2ed9Sahoka } 693*060d2ed9Sahoka 694*060d2ed9Sahoka /* --------------------------------------------------------------------- */ 695*060d2ed9Sahoka 696*060d2ed9Sahoka /* ARGSUSED2 */ 697*060d2ed9Sahoka static int 698*060d2ed9Sahoka chfs_statvfs(struct mount *mp, struct statvfs *sbp) 699*060d2ed9Sahoka { 700*060d2ed9Sahoka struct chfs_mount *chmp; 701*060d2ed9Sahoka struct ufsmount *ump; 702*060d2ed9Sahoka dbg("statvfs\n"); 703*060d2ed9Sahoka 704*060d2ed9Sahoka ump = VFSTOUFS(mp); 705*060d2ed9Sahoka chmp = ump->um_chfs; 706*060d2ed9Sahoka 707*060d2ed9Sahoka sbp->f_flag = mp->mnt_flag; 708*060d2ed9Sahoka sbp->f_bsize = chmp->chm_ebh->eb_size; 709*060d2ed9Sahoka sbp->f_frsize = chmp->chm_ebh->eb_size; 710*060d2ed9Sahoka sbp->f_iosize = chmp->chm_ebh->eb_size; 711*060d2ed9Sahoka 712*060d2ed9Sahoka sbp->f_blocks = chmp->chm_ebh->peb_nr; 713*060d2ed9Sahoka sbp->f_files = 0; 714*060d2ed9Sahoka sbp->f_bavail = chmp->chm_nr_free_blocks - chmp->chm_resv_blocks_write; 715*060d2ed9Sahoka #if 0 716*060d2ed9Sahoka printf("chmp->chm_nr_free_blocks: %jd\n", 717*060d2ed9Sahoka (intmax_t )chmp->chm_nr_free_blocks); 718*060d2ed9Sahoka printf("chmp->chm_resv_blocks_write: %jd\n", 719*060d2ed9Sahoka (intmax_t) chmp->chm_resv_blocks_write); 720*060d2ed9Sahoka printf("chmp->chm_ebh->peb_nr: %jd\n", 721*060d2ed9Sahoka (intmax_t) chmp->chm_ebh->peb_nr); 722*060d2ed9Sahoka #endif 723*060d2ed9Sahoka 724*060d2ed9Sahoka sbp->f_bfree = chmp->chm_nr_free_blocks; 725*060d2ed9Sahoka sbp->f_bresvd = chmp->chm_resv_blocks_write; 726*060d2ed9Sahoka 727*060d2ed9Sahoka /* FFS specific */ 728*060d2ed9Sahoka sbp->f_ffree = 0; 729*060d2ed9Sahoka sbp->f_favail = 0; 730*060d2ed9Sahoka sbp->f_fresvd = 0; 731*060d2ed9Sahoka 732*060d2ed9Sahoka copy_statvfs_info(sbp, mp); 733*060d2ed9Sahoka 734*060d2ed9Sahoka return 0; 735*060d2ed9Sahoka } 736*060d2ed9Sahoka 737*060d2ed9Sahoka /* --------------------------------------------------------------------- */ 738*060d2ed9Sahoka 739*060d2ed9Sahoka /* ARGSUSED0 */ 740*060d2ed9Sahoka static int 741*060d2ed9Sahoka chfs_sync(struct mount *mp, int waitfor, 742*060d2ed9Sahoka kauth_cred_t uc) 743*060d2ed9Sahoka { 744*060d2ed9Sahoka return 0; 745*060d2ed9Sahoka } 746*060d2ed9Sahoka 747*060d2ed9Sahoka /* --------------------------------------------------------------------- */ 748*060d2ed9Sahoka 749*060d2ed9Sahoka static void 750*060d2ed9Sahoka chfs_init(void) 751*060d2ed9Sahoka { 752*060d2ed9Sahoka chfs_alloc_pool_caches(); 753*060d2ed9Sahoka chfs_ihashinit(); 754*060d2ed9Sahoka pool_init(&chfs_inode_pool, sizeof(struct chfs_inode), 0, 0, 0, 755*060d2ed9Sahoka "chfsinopl", &pool_allocator_nointr, IPL_NONE); 756*060d2ed9Sahoka ufs_init(); 757*060d2ed9Sahoka } 758*060d2ed9Sahoka 759*060d2ed9Sahoka /* --------------------------------------------------------------------- */ 760*060d2ed9Sahoka 761*060d2ed9Sahoka static void 762*060d2ed9Sahoka chfs_reinit(void) 763*060d2ed9Sahoka { 764*060d2ed9Sahoka chfs_ihashreinit(); 765*060d2ed9Sahoka ufs_reinit(); 766*060d2ed9Sahoka } 767*060d2ed9Sahoka 768*060d2ed9Sahoka /* --------------------------------------------------------------------- */ 769*060d2ed9Sahoka 770*060d2ed9Sahoka static void 771*060d2ed9Sahoka chfs_done(void) 772*060d2ed9Sahoka { 773*060d2ed9Sahoka ufs_done(); 774*060d2ed9Sahoka chfs_ihashdone(); 775*060d2ed9Sahoka pool_destroy(&chfs_inode_pool); 776*060d2ed9Sahoka chfs_destroy_pool_caches(); 777*060d2ed9Sahoka } 778*060d2ed9Sahoka 779*060d2ed9Sahoka /* --------------------------------------------------------------------- */ 780*060d2ed9Sahoka 781*060d2ed9Sahoka static int 782*060d2ed9Sahoka chfs_snapshot(struct mount *mp, struct vnode *vp, 783*060d2ed9Sahoka struct timespec *ctime) 784*060d2ed9Sahoka { 785*060d2ed9Sahoka return ENODEV; 786*060d2ed9Sahoka } 787*060d2ed9Sahoka 788*060d2ed9Sahoka /* --------------------------------------------------------------------- */ 789*060d2ed9Sahoka 790*060d2ed9Sahoka /* 791*060d2ed9Sahoka * chfs vfs operations. 792*060d2ed9Sahoka */ 793*060d2ed9Sahoka 794*060d2ed9Sahoka extern const struct vnodeopv_desc chfs_fifoop_opv_desc; 795*060d2ed9Sahoka extern const struct vnodeopv_desc chfs_specop_opv_desc; 796*060d2ed9Sahoka extern const struct vnodeopv_desc chfs_vnodeop_opv_desc; 797*060d2ed9Sahoka 798*060d2ed9Sahoka const struct vnodeopv_desc * const chfs_vnodeopv_descs[] = { 799*060d2ed9Sahoka &chfs_fifoop_opv_desc, 800*060d2ed9Sahoka &chfs_specop_opv_desc, 801*060d2ed9Sahoka &chfs_vnodeop_opv_desc, 802*060d2ed9Sahoka NULL, 803*060d2ed9Sahoka }; 804*060d2ed9Sahoka 805*060d2ed9Sahoka struct vfsops chfs_vfsops = { 806*060d2ed9Sahoka MOUNT_CHFS, /* vfs_name */ 807*060d2ed9Sahoka sizeof (struct chfs_args), 808*060d2ed9Sahoka chfs_mount, /* vfs_mount */ 809*060d2ed9Sahoka chfs_start, /* vfs_start */ 810*060d2ed9Sahoka chfs_unmount, /* vfs_unmount */ 811*060d2ed9Sahoka chfs_root, /* vfs_root */ 812*060d2ed9Sahoka ufs_quotactl, /* vfs_quotactl */ 813*060d2ed9Sahoka chfs_statvfs, /* vfs_statvfs */ 814*060d2ed9Sahoka chfs_sync, /* vfs_sync */ 815*060d2ed9Sahoka chfs_vget, /* vfs_vget */ 816*060d2ed9Sahoka chfs_fhtovp, /* vfs_fhtovp */ 817*060d2ed9Sahoka chfs_vptofh, /* vfs_vptofh */ 818*060d2ed9Sahoka chfs_init, /* vfs_init */ 819*060d2ed9Sahoka chfs_reinit, /* vfs_reinit */ 820*060d2ed9Sahoka chfs_done, /* vfs_done */ 821*060d2ed9Sahoka NULL, /* vfs_mountroot */ 822*060d2ed9Sahoka chfs_snapshot, /* vfs_snapshot */ 823*060d2ed9Sahoka vfs_stdextattrctl, /* vfs_extattrctl */ 824*060d2ed9Sahoka (void *)eopnotsupp, /* vfs_suspendctl */ 825*060d2ed9Sahoka genfs_renamelock_enter, 826*060d2ed9Sahoka genfs_renamelock_exit, 827*060d2ed9Sahoka (void *)eopnotsupp, 828*060d2ed9Sahoka chfs_vnodeopv_descs, 829*060d2ed9Sahoka 0, /* vfs_refcount */ 830*060d2ed9Sahoka { NULL, NULL }, 831*060d2ed9Sahoka }; 832*060d2ed9Sahoka 833*060d2ed9Sahoka static int 834*060d2ed9Sahoka chfs_modcmd(modcmd_t cmd, void *arg) 835*060d2ed9Sahoka { 836*060d2ed9Sahoka switch (cmd) { 837*060d2ed9Sahoka case MODULE_CMD_INIT: 838*060d2ed9Sahoka return vfs_attach(&chfs_vfsops); 839*060d2ed9Sahoka case MODULE_CMD_FINI: 840*060d2ed9Sahoka return vfs_detach(&chfs_vfsops); 841*060d2ed9Sahoka default: 842*060d2ed9Sahoka return ENOTTY; 843*060d2ed9Sahoka } 844*060d2ed9Sahoka } 845