1 /* $NetBSD: dtfs.c,v 1.40 2009/12/04 13:43:28 pooka Exp $ */
4 * Copyright (c) 2006 Antti Kantee. All Rights Reserved.
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
9 * 1. Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * 2. Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
15 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
16 * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
17 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
18 * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
19 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
20 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
21 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
22 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
23 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
24 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 * Delectable Test File System: a simple in-memory file system which
30 * demonstrates the use of puffs.
31 * (a.k.a. Detrempe FS ...)
34 #include <sys/types.h>
48 #ifdef DEEP_ROOTED_CLUE
49 #define FSNAME "detrempe"
53 #define MAXREQMAGIC -37
55 static struct puffs_usermount
*gpu
;
56 static struct dtfs_mount gdtm
;
60 static void usage(void);
66 fprintf(stderr
, "usage: %s [-bsdftl] [-c hashbuckets] [-m maxreqsize] "
67 "[-n typename]\n [-o mntopt] [-o puffsopt] [-p prot] "
68 "[-r rootnodetype]\n detrempe /mountpoint\n", getprogname());
73 wipe_the_sleep_out_of_my_eyes(int v
)
76 gdtm
.dtm_needwakeup
++;
80 loopfun(struct puffs_usermount
*pu
)
82 struct dtfs_mount
*dtm
= puffs_getspecific(pu
);
85 while (dtm
->dtm_needwakeup
) {
86 dtm
->dtm_needwakeup
--;
87 dp
= LIST_FIRST(&dtm
->dtm_pollent
);
91 LIST_REMOVE(dp
, dp_entries
);
92 puffs_cc_continue(dp
->dp_pcc
);
97 main(int argc
, char *argv
[])
101 struct puffs_usermount
*pu
;
102 struct puffs_pathobj
*po_root
;
103 struct puffs_ops
*pops
;
105 const char *typename
;
108 int pflags
, detach
, mntflags
;
113 setprogname(argv
[0]);
119 pflags
= PUFFS_KFLAG_IAONDEMAND
;
121 maxreqsize
= MAXREQMAGIC
;
122 gdtm
.dtm_allowprot
= VM_PROT_ALL
;
123 while ((ch
= getopt(argc
, argv
, "bc:dfilm:n:o:p:r:st")) != -1) {
125 case 'b': /* build paths, for debugging the feature */
126 pflags
|= PUFFS_FLAG_BUILDPATH
;
129 khashbuckets
= atoi(optarg
);
135 pflags
|= PUFFS_KFLAG_LOOKUP_FULLPNBUF
;
138 pflags
&= ~PUFFS_KFLAG_IAONDEMAND
;
144 maxreqsize
= atoi(optarg
);
150 mp
= getmntopts(optarg
, puffsmopts
, &mntflags
, &pflags
);
152 err(1, "getmntopts");
156 gdtm
.dtm_allowprot
= atoi(optarg
);
157 if ((gdtm
.dtm_allowprot
| VM_PROT_ALL
) != VM_PROT_ALL
)
163 case 's': /* stay on top */
167 pflags
|= PUFFS_KFLAG_WTCACHE
;
174 if (pflags
& PUFFS_FLAG_OPDUMP
)
184 PUFFSOP_SET(pops
, dtfs
, fs
, statvfs
);
185 PUFFSOP_SET(pops
, dtfs
, fs
, unmount
);
186 PUFFSOP_SETFSNOP(pops
, sync
);
187 PUFFSOP_SET(pops
, dtfs
, fs
, fhtonode
);
188 PUFFSOP_SET(pops
, dtfs
, fs
, nodetofh
);
190 PUFFSOP_SET(pops
, dtfs
, node
, lookup
);
191 PUFFSOP_SET(pops
, dtfs
, node
, access
);
192 PUFFSOP_SET(pops
, puffs_genfs
, node
, getattr
);
193 PUFFSOP_SET(pops
, dtfs
, node
, setattr
);
194 PUFFSOP_SET(pops
, dtfs
, node
, create
);
195 PUFFSOP_SET(pops
, dtfs
, node
, remove
);
196 PUFFSOP_SET(pops
, dtfs
, node
, readdir
);
197 PUFFSOP_SET(pops
, dtfs
, node
, poll
);
198 PUFFSOP_SET(pops
, dtfs
, node
, mmap
);
199 PUFFSOP_SET(pops
, dtfs
, node
, mkdir
);
200 PUFFSOP_SET(pops
, dtfs
, node
, rmdir
);
201 PUFFSOP_SET(pops
, dtfs
, node
, rename
);
202 PUFFSOP_SET(pops
, dtfs
, node
, read
);
203 PUFFSOP_SET(pops
, dtfs
, node
, write
);
204 PUFFSOP_SET(pops
, dtfs
, node
, link
);
205 PUFFSOP_SET(pops
, dtfs
, node
, symlink
);
206 PUFFSOP_SET(pops
, dtfs
, node
, readlink
);
207 PUFFSOP_SET(pops
, dtfs
, node
, mknod
);
208 PUFFSOP_SET(pops
, dtfs
, node
, reclaim
);
210 srandom(time(NULL
)); /* for random generation numbers */
212 pu
= puffs_init(pops
, _PATH_PUFFS
, typename
, &gdtm
, pflags
);
217 puffs_setfhsize(pu
, sizeof(struct dtfs_fid
),
218 PUFFS_FHFLAG_NFSV2
| PUFFS_FHFLAG_NFSV3
219 | (dynamicfh
? PUFFS_FHFLAG_DYNAMIC
: 0));
220 puffs_setncookiehash(pu
, khashbuckets
);
222 if (signal(SIGALRM
, wipe_the_sleep_out_of_my_eyes
) == SIG_ERR
)
223 warn("cannot set alarm sighandler");
226 if (dtfs_domount(pu
, rtstr
) != 0)
227 errx(1, "dtfs_domount failed");
229 po_root
= puffs_getrootpathobj(pu
);
230 po_root
->po_path
= argv
[0];
231 po_root
->po_len
= strlen(argv
[0]);
233 /* often enough for testing poll */
236 puffs_ml_setloopfn(pu
, loopfun
);
237 puffs_ml_settimeout(pu
, &ts
);
239 if (maxreqsize
!= MAXREQMAGIC
)
240 puffs_setmaxreqlen(pu
, maxreqsize
);
242 puffs_set_errnotify(pu
, puffs_kernerr_abort
);
244 if (puffs_daemon(pu
, 1, 1) == -1)
245 err(1, "puffs_daemon");
247 if (puffs_mount(pu
, argv
[1], mntflags
, puffs_getroot(pu
)) == -1)
249 if (puffs_mainloop(pu
) == -1)