dtfs.c revision 272343
1249259Sdim/* $NetBSD: dtfs.c,v 1.2 2010/07/21 06:58:25 pooka Exp $ */ 2249259Sdim 3249259Sdim/* 4249259Sdim * Copyright (c) 2006 Antti Kantee. All Rights Reserved. 5249259Sdim * 6249259Sdim * Redistribution and use in source and binary forms, with or without 7249259Sdim * modification, are permitted provided that the following conditions 8249259Sdim * are met: 9249259Sdim * 1. Redistributions of source code must retain the above copyright 10249259Sdim * notice, this list of conditions and the following disclaimer. 11249259Sdim * 2. Redistributions in binary form must reproduce the above copyright 12249259Sdim * notice, this list of conditions and the following disclaimer in the 13249259Sdim * documentation and/or other materials provided with the distribution. 14249259Sdim * 15288943Sdim * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS 16249259Sdim * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 17249259Sdim * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 18249259Sdim * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 19249259Sdim * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 20249259Sdim * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 21249259Sdim * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 22249259Sdim * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 23249259Sdim * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 24249259Sdim * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 25249259Sdim * SUCH DAMAGE. 26249259Sdim */ 27249259Sdim 28276479Sdim/* 29249259Sdim * Delectable Test File System: a simple in-memory file system which 30249259Sdim * demonstrates the use of puffs. 31249259Sdim * (a.k.a. Detrempe FS ...) 32249259Sdim */ 33249259Sdim 34249259Sdim#include <sys/types.h> 35249259Sdim 36249259Sdim#include <err.h> 37249259Sdim#include <mntopts.h> 38249259Sdim#include <paths.h> 39249259Sdim#include <puffs.h> 40280031Sdim#include <signal.h> 41280031Sdim#include <stdio.h> 42249259Sdim#include <stdlib.h> 43249259Sdim#include <string.h> 44249259Sdim#include <unistd.h> 45249259Sdim 46249259Sdim#include "dtfs.h" 47249259Sdim 48276479Sdim#ifdef DEEP_ROOTED_CLUE 49288943Sdim#define FSNAME "detrempe" 50288943Sdim#else 51249259Sdim#define FSNAME "dt" 52249259Sdim#endif 53288943Sdim#define MAXREQMAGIC -37 54288943Sdim 55288943Sdimstatic struct puffs_usermount *gpu; 56288943Sdimstatic struct dtfs_mount gdtm; 57288943Sdimint dynamicfh; 58249259Sdimint straightflush; 59249259Sdim 60249259Sdimstatic void usage(void); 61249259Sdim 62249259Sdimstatic void 63249259Sdimusage() 64249259Sdim{ 65249259Sdim 66249259Sdim fprintf(stderr, "usage: %s [-bsdftl] [-c hashbuckets] [-m maxreqsize] " 67249259Sdim "[-n typename]\n [-o mntopt] [-o puffsopt] [-p prot] " 68249259Sdim "[-r rootnodetype]\n detrempe /mountpoint\n", getprogname()); 69249259Sdim exit(1); 70249259Sdim} 71249259Sdim 72249259Sdimstatic void 73249259Sdimwipe_the_sleep_out_of_my_eyes(int v) 74249259Sdim{ 75249259Sdim 76249259Sdim gdtm.dtm_needwakeup++; 77249259Sdim} 78249259Sdim 79249259Sdimstatic void 80249259Sdimloopfun(struct puffs_usermount *pu) 81249259Sdim{ 82249259Sdim struct dtfs_mount *dtm = puffs_getspecific(pu); 83249259Sdim struct dtfs_poll *dp; 84249259Sdim 85249259Sdim while (dtm->dtm_needwakeup) { 86249259Sdim dtm->dtm_needwakeup--; 87249259Sdim dp = LIST_FIRST(&dtm->dtm_pollent); 88249259Sdim if (dp == NULL) 89249259Sdim return; 90249259Sdim 91249259Sdim LIST_REMOVE(dp, dp_entries); 92249259Sdim puffs_cc_continue(dp->dp_pcc); 93249259Sdim } 94249259Sdim} 95249259Sdim 96249259Sdimint 97249259Sdimmain(int argc, char *argv[]) 98249259Sdim{ 99249259Sdim extern char *optarg; 100249259Sdim extern int optind; 101249259Sdim struct puffs_usermount *pu; 102249259Sdim struct puffs_pathobj *po_root; 103249259Sdim struct puffs_ops *pops; 104249259Sdim struct timespec ts; 105249259Sdim const char *typename; 106249259Sdim char *rtstr; 107249259Sdim mntoptparse_t mp; 108249259Sdim int pflags, detach, mntflags; 109249259Sdim int ch; 110249259Sdim int khashbuckets; 111249259Sdim int maxreqsize; 112249259Sdim 113249259Sdim setprogname(argv[0]); 114249259Sdim 115249259Sdim rtstr = NULL; 116249259Sdim detach = 1; 117249259Sdim mntflags = 0; 118249259Sdim khashbuckets = 256; 119249259Sdim pflags = PUFFS_KFLAG_IAONDEMAND; 120249259Sdim typename = FSNAME; 121249259Sdim maxreqsize = MAXREQMAGIC; 122249259Sdim gdtm.dtm_allowprot = VM_PROT_ALL; 123249259Sdim while ((ch = getopt(argc, argv, "bc:dfilm:n:o:p:r:st")) != -1) { 124249259Sdim switch (ch) { 125249259Sdim case 'b': /* build paths, for debugging the feature */ 126249259Sdim pflags |= PUFFS_FLAG_BUILDPATH; 127249259Sdim break; 128249259Sdim case 'c': 129249259Sdim khashbuckets = atoi(optarg); 130249259Sdim break; 131249259Sdim case 'd': 132249259Sdim dynamicfh = 1; 133249259Sdim break; 134249259Sdim case 'f': 135249259Sdim pflags |= PUFFS_KFLAG_LOOKUP_FULLPNBUF; 136249259Sdim break; 137249259Sdim case 'i': 138249259Sdim pflags &= ~PUFFS_KFLAG_IAONDEMAND; 139249259Sdim break; 140249259Sdim case 'l': 141251662Sdim straightflush = 1; 142249259Sdim break; 143249259Sdim case 'm': 144249259Sdim maxreqsize = atoi(optarg); 145249259Sdim break; 146249259Sdim case 'n': 147249259Sdim typename = optarg; 148249259Sdim break; 149249259Sdim case 'o': 150249259Sdim mp = getmntopts(optarg, puffsmopts, &mntflags, &pflags); 151249259Sdim if (mp == NULL) 152249259Sdim err(1, "getmntopts"); 153249259Sdim freemntopts(mp); 154249259Sdim break; 155249259Sdim case 'p': 156249259Sdim gdtm.dtm_allowprot = atoi(optarg); 157249259Sdim if ((gdtm.dtm_allowprot | VM_PROT_ALL) != VM_PROT_ALL) 158249259Sdim usage(); 159249259Sdim break; 160249259Sdim case 'r': 161249259Sdim rtstr = optarg; 162249259Sdim break; 163249259Sdim case 's': /* stay on top */ 164249259Sdim detach = 0; 165249259Sdim break; 166249259Sdim case 't': 167249259Sdim pflags |= PUFFS_KFLAG_WTCACHE; 168249259Sdim break; 169249259Sdim default: 170249259Sdim usage(); 171249259Sdim /*NOTREACHED*/ 172249259Sdim } 173249259Sdim } 174249259Sdim if (pflags & PUFFS_FLAG_OPDUMP) 175249259Sdim detach = 0; 176249259Sdim argc -= optind; 177249259Sdim argv += optind; 178249259Sdim 179249259Sdim if (argc != 2) 180249259Sdim usage(); 181249259Sdim 182249259Sdim PUFFSOP_INIT(pops); 183249259Sdim 184249259Sdim PUFFSOP_SET(pops, dtfs, fs, statvfs); 185249259Sdim PUFFSOP_SET(pops, dtfs, fs, unmount); 186249259Sdim PUFFSOP_SETFSNOP(pops, sync); 187249259Sdim PUFFSOP_SET(pops, dtfs, fs, fhtonode); 188249259Sdim PUFFSOP_SET(pops, dtfs, fs, nodetofh); 189249259Sdim 190249259Sdim PUFFSOP_SET(pops, dtfs, node, lookup); 191249259Sdim PUFFSOP_SET(pops, dtfs, node, access); 192249259Sdim PUFFSOP_SET(pops, puffs_genfs, node, getattr); 193249259Sdim PUFFSOP_SET(pops, dtfs, node, setattr); 194249259Sdim PUFFSOP_SET(pops, dtfs, node, create); 195249259Sdim PUFFSOP_SET(pops, dtfs, node, remove); 196249259Sdim PUFFSOP_SET(pops, dtfs, node, readdir); 197249259Sdim PUFFSOP_SET(pops, dtfs, node, poll); 198249259Sdim PUFFSOP_SET(pops, dtfs, node, mmap); 199249259Sdim PUFFSOP_SET(pops, dtfs, node, mkdir); 200249259Sdim PUFFSOP_SET(pops, dtfs, node, rmdir); 201249259Sdim PUFFSOP_SET(pops, dtfs, node, rename); 202249259Sdim PUFFSOP_SET(pops, dtfs, node, read); 203249259Sdim PUFFSOP_SET(pops, dtfs, node, write); 204249259Sdim PUFFSOP_SET(pops, dtfs, node, link); 205249259Sdim PUFFSOP_SET(pops, dtfs, node, symlink); 206249259Sdim PUFFSOP_SET(pops, dtfs, node, readlink); 207249259Sdim PUFFSOP_SET(pops, dtfs, node, mknod); 208249259Sdim PUFFSOP_SET(pops, dtfs, node, inactive); 209249259Sdim PUFFSOP_SET(pops, dtfs, node, pathconf); 210249259Sdim PUFFSOP_SET(pops, dtfs, node, reclaim); 211249259Sdim 212249259Sdim srandom(time(NULL)); /* for random generation numbers */ 213249259Sdim 214249259Sdim pu = puffs_init(pops, _PATH_PUFFS, typename, &gdtm, pflags); 215249259Sdim if (pu == NULL) 216249259Sdim err(1, "init"); 217249259Sdim gpu = pu; 218249259Sdim 219249259Sdim puffs_setfhsize(pu, sizeof(struct dtfs_fid), 220249259Sdim PUFFS_FHFLAG_NFSV2 | PUFFS_FHFLAG_NFSV3 221249259Sdim | (dynamicfh ? PUFFS_FHFLAG_DYNAMIC : 0)); 222249259Sdim puffs_setncookiehash(pu, khashbuckets); 223249259Sdim 224249259Sdim if (signal(SIGALRM, wipe_the_sleep_out_of_my_eyes) == SIG_ERR) 225249259Sdim warn("cannot set alarm sighandler"); 226249259Sdim 227249259Sdim /* init */ 228249259Sdim if (dtfs_domount(pu, rtstr) != 0) 229249259Sdim errx(1, "dtfs_domount failed"); 230249259Sdim 231249259Sdim po_root = puffs_getrootpathobj(pu); 232249259Sdim po_root->po_path = argv[0]; 233249259Sdim po_root->po_len = strlen(argv[0]); 234249259Sdim 235276479Sdim /* often enough for testing poll */ 236288943Sdim ts.tv_sec = 1; 237288943Sdim ts.tv_nsec = 0; 238249259Sdim puffs_ml_setloopfn(pu, loopfun); 239288943Sdim puffs_ml_settimeout(pu, &ts); 240288943Sdim 241288943Sdim if (maxreqsize != MAXREQMAGIC) 242288943Sdim puffs_setmaxreqlen(pu, maxreqsize); 243288943Sdim 244249259Sdim puffs_set_errnotify(pu, puffs_kernerr_abort); 245249259Sdim if (detach) 246249259Sdim if (puffs_daemon(pu, 1, 1) == -1) 247249259Sdim err(1, "puffs_daemon"); 248249259Sdim 249249259Sdim if (puffs_mount(pu, argv[1], mntflags, puffs_getroot(pu)) == -1) 250249259Sdim err(1, "mount"); 251249259Sdim if (puffs_mainloop(pu) == -1) 252249259Sdim err(1, "mainloop"); 253249259Sdim 254249259Sdim return 0; 255249259Sdim} 256249259Sdim