Annotation of src/lib/libp2k/p2k.c, Revision 1.14
1.14 ! pooka 1: /* $NetBSD: p2k.c,v 1.13 2009/05/03 20:26:42 pooka Exp $ */
1.1 pooka 2:
3: /*
4: * Copyright (c) 2007 Antti Kantee. All Rights Reserved.
5: *
6: * Development of this software was supported by Google Summer of Code.
7: *
8: * Redistribution and use in source and binary forms, with or without
9: * modification, are permitted provided that the following conditions
10: * are met:
11: * 1. Redistributions of source code must retain the above copyright
12: * notice, this list of conditions and the following disclaimer.
13: * 2. Redistributions in binary form must reproduce the above copyright
14: * notice, this list of conditions and the following disclaimer in the
15: * documentation and/or other materials provided with the distribution.
16: *
17: * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
18: * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
19: * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
20: * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
21: * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22: * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
23: * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24: * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25: * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
26: * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
27: * SUCH DAMAGE.
28: */
29:
30: /*
31: * puffs 2k, i.e. puffs 2 kernel. Converts the puffs protocol to
32: * the kernel vfs protocol and vice versa.
33: *
34: * A word about reference counting: puffs in the kernel is the king of
35: * reference counting. We must maintain a vnode alive and kicking
36: * until the kernel tells us to reclaim it. Therefore we make sure
37: * we never accidentally lose a vnode. Before calling operations which
38: * decrease the refcount we always bump the refcount up to compensate.
39: * Come inactive, if the file system thinks that the vnode should be
40: * put out of its misery, it will set the recycle flag. We use this
41: * to tell the kernel to reclaim the vnode. Only in reclaim do we
42: * really nuke the last reference.
43: */
44:
1.4 pooka 45: #include <sys/cdefs.h>
1.1 pooka 46: #include <sys/mount.h>
47: #include <sys/param.h>
48: #include <sys/vnode.h>
49: #include <sys/lock.h>
50: #include <sys/namei.h>
51: #include <sys/dirent.h>
52:
53: #include <assert.h>
54: #include <errno.h>
55: #include <puffs.h>
56: #include <stdlib.h>
1.10 pooka 57: #include <stdio.h>
1.1 pooka 58:
59: #include <rump/rump.h>
60: #include <rump/p2k.h>
61: #include <rump/ukfs.h>
62:
63: PUFFSOP_PROTOS(p2k)
64:
65: static kauth_cred_t
66: cred_create(const struct puffs_cred *pcr)
67: {
68: gid_t groups[NGROUPS];
69: uid_t uid;
70: gid_t gid;
71: short ngroups = 0;
72:
73: if (puffs_cred_getuid(pcr, &uid) == -1)
74: uid = 0;
75: if (puffs_cred_getgid(pcr, &gid) == -1)
76: gid = 0;
77: puffs_cred_getgroups(pcr, groups, &ngroups);
78:
79: /* LINTED: ngroups is ok */
80: return rump_cred_create(uid, gid, ngroups, groups);
81: }
82:
83: static __inline void
84: cred_destroy(kauth_cred_t cred)
85: {
86:
1.12 pooka 87: rump_cred_put(cred);
1.1 pooka 88: }
89:
90: static struct componentname *
91: makecn(const struct puffs_cn *pcn)
92: {
93: kauth_cred_t cred;
94:
95: cred = cred_create(pcn->pcn_cred);
96: /* LINTED: prehistoric types in first two args */
97: return rump_makecn(pcn->pcn_nameiop, pcn->pcn_flags, pcn->pcn_name,
98: pcn->pcn_namelen, cred, curlwp);
99: }
100:
101: static __inline void
102: freecn(struct componentname *cnp, int flags)
103: {
104:
105: rump_freecn(cnp, flags | RUMPCN_FREECRED);
106: }
107:
108: static void
109: makelwp(struct puffs_usermount *pu)
110: {
111: pid_t pid;
112: lwpid_t lid;
113:
114: puffs_cc_getcaller(puffs_cc_getcc(pu), &pid, &lid);
115: rump_setup_curlwp(pid, lid, 1);
116: }
117:
118: /*ARGSUSED*/
119: static void
120: clearlwp(struct puffs_usermount *pu)
121: {
122:
1.4 pooka 123: /*
124: * XXX: because of the vnode reference counting lossage, we
125: * can't clear the curlwp if we unmounted succesfully.
126: * Therefore, don't do it to avoid a diagnostic panic.
127: * So this currently leaks a process structure in that case,
128: * but since p2k is rarely used multiple times in a single
129: * process, it's more like a feature than a bug (yea, I'm
130: * good at lying to myself).
131: */
132: if (__predict_false(puffs_getstate(pu) != PUFFS_STATE_UNMOUNTED))
133: rump_clear_curlwp();
1.1 pooka 134: }
135:
1.11 pooka 136: /*ARGSUSED*/
1.10 pooka 137: static void
138: p2k_errcatcher(struct puffs_usermount *pu, uint8_t type, int error,
139: const char *str, puffs_cookie_t cook)
140: {
141:
142: fprintf(stderr, "type %d, error %d, cookie %p (%s)\n",
143: type, error, cook, str);
144:
145: /*
146: * Trap all EINVAL responses to lookup. It most likely means
147: * that we supplied VNON/VBAD as the type. The real kernel
148: * doesn't panic from this either, but just handles it.
149: */
150: if (type != PUFFS_VN_LOOKUP && error == EINVAL)
151: abort();
152: }
153:
1.1 pooka 154: int
155: p2k_run_fs(const char *vfsname, const char *devpath, const char *mountpath,
156: int mntflags, void *arg, size_t alen, uint32_t puffs_flags)
157: {
158: char typebuf[PUFFS_TYPELEN];
159: struct puffs_ops *pops;
1.7 pooka 160: struct puffs_usermount *pu = NULL;
1.1 pooka 161: struct puffs_node *pn_root;
162: struct vnode *rvp;
1.7 pooka 163: struct ukfs *ukfs = NULL;
1.1 pooka 164: extern int puffs_fakecc;
1.7 pooka 165: int rv = -1, sverrno;
1.6 pooka 166: bool dodaemon;
1.1 pooka 167:
168: PUFFSOP_INIT(pops);
169:
170: PUFFSOP_SET(pops, p2k, fs, statvfs);
171: PUFFSOP_SET(pops, p2k, fs, unmount);
172: PUFFSOP_SET(pops, p2k, fs, sync);
173: PUFFSOP_SET(pops, p2k, fs, fhtonode);
174: PUFFSOP_SET(pops, p2k, fs, nodetofh);
175:
176: PUFFSOP_SET(pops, p2k, node, lookup);
177: PUFFSOP_SET(pops, p2k, node, create);
178: PUFFSOP_SET(pops, p2k, node, mknod);
179: PUFFSOP_SET(pops, p2k, node, open);
180: PUFFSOP_SET(pops, p2k, node, close);
181: PUFFSOP_SET(pops, p2k, node, access);
182: PUFFSOP_SET(pops, p2k, node, getattr);
183: PUFFSOP_SET(pops, p2k, node, setattr);
184: #if 0
185: PUFFSOP_SET(pops, p2k, node, poll);
186: #endif
187: PUFFSOP_SET(pops, p2k, node, mmap);
188: PUFFSOP_SET(pops, p2k, node, fsync);
189: PUFFSOP_SET(pops, p2k, node, seek);
190: PUFFSOP_SET(pops, p2k, node, remove);
191: PUFFSOP_SET(pops, p2k, node, link);
192: PUFFSOP_SET(pops, p2k, node, rename);
193: PUFFSOP_SET(pops, p2k, node, mkdir);
194: PUFFSOP_SET(pops, p2k, node, rmdir);
195: PUFFSOP_SET(pops, p2k, node, symlink);
196: PUFFSOP_SET(pops, p2k, node, readdir);
197: PUFFSOP_SET(pops, p2k, node, readlink);
198: PUFFSOP_SET(pops, p2k, node, read);
199: PUFFSOP_SET(pops, p2k, node, write);
200:
201: PUFFSOP_SET(pops, p2k, node, inactive);
202: PUFFSOP_SET(pops, p2k, node, reclaim);
203:
1.6 pooka 204: dodaemon = true;
205: if (getenv("P2K_DEBUG") != NULL) {
206: puffs_flags |= PUFFS_FLAG_OPDUMP;
207: dodaemon = false;
208: }
1.8 pooka 209: if (getenv("P2K_NODETACH") != NULL) {
210: dodaemon = false;
211: }
1.13 pooka 212: if (getenv("P2K_NOCACHE_PAGE") != NULL) {
213: puffs_flags |= PUFFS_KFLAG_NOCACHE_PAGE;
214: }
215: if (getenv("P2K_NOCACHE_NAME") != NULL) {
216: puffs_flags |= PUFFS_KFLAG_NOCACHE_NAME;
217: }
218: if (getenv("P2K_NOCACHE") != NULL) {
219: puffs_flags |= PUFFS_KFLAG_NOCACHE;
220: }
1.6 pooka 221:
1.1 pooka 222: strcpy(typebuf, "p2k|");
223: if (strcmp(vfsname, "puffs") == 0) { /* XXX */
224: struct puffs_kargs *args = arg;
225: strlcat(typebuf, args->pa_typename, sizeof(typebuf));
1.6 pooka 226: dodaemon = false;
1.1 pooka 227: } else {
228: strlcat(typebuf, vfsname, sizeof(typebuf));
229: }
230:
1.7 pooka 231: pu = puffs_init(pops, devpath, typebuf, NULL, puffs_flags);
1.1 pooka 232: if (pu == NULL)
233: goto out;
234:
1.7 pooka 235: if (dodaemon)
236: puffs_daemon(pu, 1, 1);
237:
238: if (ukfs_init() == -1)
239: return -1;
240: ukfs = ukfs_mount(vfsname, devpath, mountpath, mntflags, arg, alen);
241: if (ukfs == NULL)
242: goto out;
243:
1.1 pooka 244: rvp = ukfs_getrvp(ukfs);
245: pn_root = puffs_pn_new(pu, rvp);
246: puffs_setroot(pu, pn_root);
247: puffs_setfhsize(pu, 0, PUFFS_FHFLAG_PASSTHROUGH);
248: puffs_setstacksize(pu, PUFFS_STACKSIZE_MIN);
249: puffs_fakecc = 1;
250:
251: puffs_set_prepost(pu, makelwp, clearlwp);
1.10 pooka 252: puffs_set_errnotify(pu, p2k_errcatcher);
1.1 pooka 253:
1.7 pooka 254: puffs_setspecific(pu, ukfs_getmp(ukfs));
1.1 pooka 255: if ((rv = puffs_mount(pu, mountpath, mntflags, rvp))== -1)
256: goto out;
257: rv = puffs_mainloop(pu);
1.7 pooka 258: puffs_exit(pu, 1);
259: pu = NULL;
1.1 pooka 260:
261: out:
262: sverrno = errno;
1.7 pooka 263: if (ukfs)
264: ukfs_release(ukfs, UKFS_RELFLAG_NOUNMOUNT);
265: if (pu)
266: puffs_cancel(pu, sverrno);
1.1 pooka 267: if (rv) {
268: errno = sverrno;
269: rv = -1;
270: }
271:
272: return rv;
273: }
274:
275: /* XXX: vn_lock() */
276: #define VLE(a) RUMP_VOP_LOCK(a, LK_EXCLUSIVE)
277: #define VLS(a) RUMP_VOP_LOCK(a, LK_SHARED)
278: #define VUL(a) RUMP_VOP_UNLOCK(a, 0);
279: #define AUL(a) assert(RUMP_VOP_ISLOCKED(a) == 0)
280:
281: int
282: p2k_fs_statvfs(struct puffs_usermount *pu, struct statvfs *sbp)
283: {
284: struct mount *mp = puffs_getspecific(pu);
285:
286: return rump_vfs_statvfs(mp, sbp);
287: }
288:
289: int
290: p2k_fs_unmount(struct puffs_usermount *pu, int flags)
291: {
292: struct mount *mp = puffs_getspecific(pu);
293: struct puffs_node *pn_root = puffs_getroot(pu);
294: struct vnode *rvp = pn_root->pn_data, *rvp2;
295: int rv;
296:
297: /*
298: * We recycle the root node already here (god knows how
299: * many references it has due to lookup). This is good
300: * because VFS_UNMOUNT would do it anyway. But it is
301: * very bad if VFS_UNMOUNT fails for a reason or another
302: * (puffs guards against busy fs, but there might be other
303: * reasons).
304: *
305: * Theoretically we're going south, sinking fast & dying
306: * out here because the old vnode will be freed and we are
307: * unlikely to get a vnode at the same address. But try
308: * anyway.
309: *
310: * XXX: reallyfixmesomeday. either introduce VFS_ROOT to
311: * puffs (blah) or check the cookie in every routine
312: * against the root cookie, which might change (blah2).
313: */
314: rump_vp_recycle_nokidding(rvp);
315: rv = rump_vfs_unmount(mp, flags);
316: if (rv) {
317: int rv2;
318:
319: rv2 = rump_vfs_root(mp, &rvp2, 0);
320: assert(rv2 == 0 && rvp == rvp2);
321: }
322: return rv;
323: }
324:
325: int
326: p2k_fs_sync(struct puffs_usermount *pu, int waitfor,
327: const struct puffs_cred *pcr)
328: {
329: struct mount *mp = puffs_getspecific(pu);
330: kauth_cred_t cred;
331: int rv;
332:
333: cred = cred_create(pcr);
334: rv = rump_vfs_sync(mp, waitfor, (kauth_cred_t)cred);
335: cred_destroy(cred);
336:
337: return rv;
338: }
339:
340: /*ARGSUSED*/
341: int
342: p2k_fs_fhtonode(struct puffs_usermount *pu, void *fid, size_t fidsize,
343: struct puffs_newinfo *pni)
344: {
345: struct mount *mp = puffs_getspecific(pu);
346: struct vnode *vp;
347: enum vtype vtype;
348: voff_t vsize;
1.14 ! pooka 349: uint64_t rdev; /* XXX: uint64_t because of stack overwrite in compat */
1.1 pooka 350: int rv;
351:
352: rv = rump_vfs_fhtovp(mp, fid, &vp);
353: if (rv)
354: return rv;
355:
356: puffs_newinfo_setcookie(pni, vp);
1.14 ! pooka 357: rump_getvninfo(vp, &vtype, &vsize, (void *)&rdev);
1.1 pooka 358: puffs_newinfo_setvtype(pni, vtype);
359: puffs_newinfo_setsize(pni, vsize);
360: puffs_newinfo_setrdev(pni, rdev);
361:
362: return 0;
363: }
364:
365: /*ARGSUSED*/
366: int
1.3 pooka 367: p2k_fs_nodetofh(struct puffs_usermount *pu, puffs_cookie_t cookie, void *fid,
1.1 pooka 368: size_t *fidsize)
369: {
370: struct vnode *vp = cookie;
371:
372: return rump_vfs_vptofh(vp, fid, fidsize);
373: }
374:
375: /*ARGSUSED*/
376: int
1.3 pooka 377: p2k_node_lookup(struct puffs_usermount *pu, puffs_cookie_t opc,
1.1 pooka 378: struct puffs_newinfo *pni, const struct puffs_cn *pcn)
379: {
380: struct componentname *cn;
381: struct vnode *vp;
382: enum vtype vtype;
383: voff_t vsize;
1.14 ! pooka 384: uint64_t rdev; /* XXX: uint64_t because of stack overwrite in compat */
1.1 pooka 385: int rv;
386:
387: cn = makecn(pcn);
388: VLE(opc);
389: rv = RUMP_VOP_LOOKUP(opc, &vp, cn);
390: VUL(opc);
391: freecn(cn, RUMPCN_ISLOOKUP);
392: if (rv) {
393: if (rv == EJUSTRETURN)
394: rv = ENOENT;
395: return rv;
396: }
397: VUL(vp);
398:
399: puffs_newinfo_setcookie(pni, vp);
1.14 ! pooka 400: rump_getvninfo(vp, &vtype, &vsize, (void *)&rdev);
1.1 pooka 401: puffs_newinfo_setvtype(pni, vtype);
402: puffs_newinfo_setsize(pni, vsize);
403: puffs_newinfo_setrdev(pni, rdev);
404:
405: return 0;
406: }
407:
1.14 ! pooka 408: #define VERS_TIMECHANGE 599000700
! 409: static int
! 410: needcompat(void)
! 411: {
! 412:
! 413: return __NetBSD_Version__ < VERS_TIMECHANGE
! 414: && rump_getversion() >= VERS_TIMECHANGE;
! 415: }
! 416:
! 417: #define DOCOMPAT(va, va_compat) \
! 418: do { \
! 419: if (needcompat()) { \
! 420: va_compat = rump_vattr_init(); \
! 421: rump_vattr50_to_vattr(va, va_compat); \
! 422: } else { \
! 423: va_compat = __UNCONST(va); \
! 424: } \
! 425: } while (/*CONSTCOND*/0)
! 426:
! 427: #define UNDOCOMPAT(va_compat) \
! 428: do { \
! 429: if (needcompat()) \
! 430: rump_vattr_free(va_compat); \
! 431: } while (/*CONSTCOND*/0)
! 432:
1.1 pooka 433: /*ARGSUSED*/
434: int
1.3 pooka 435: p2k_node_create(struct puffs_usermount *pu, puffs_cookie_t opc,
1.1 pooka 436: struct puffs_newinfo *pni, const struct puffs_cn *pcn,
437: const struct vattr *vap)
438: {
439: struct componentname *cn;
1.14 ! pooka 440: struct vattr *va_x;
1.1 pooka 441: struct vnode *vp;
442: int rv;
443:
1.14 ! pooka 444: DOCOMPAT(vap, va_x);
! 445:
1.1 pooka 446: cn = makecn(pcn);
447: VLE(opc);
448: rump_vp_incref(opc);
1.14 ! pooka 449: rv = RUMP_VOP_CREATE(opc, &vp, cn, va_x);
1.1 pooka 450: AUL(opc);
451: freecn(cn, 0);
452: if (rv == 0) {
453: VUL(vp);
454: puffs_newinfo_setcookie(pni, vp);
455: }
456:
1.14 ! pooka 457: UNDOCOMPAT(va_x);
! 458:
1.1 pooka 459: return rv;
460: }
461:
462: /*ARGSUSED*/
463: int
1.3 pooka 464: p2k_node_mknod(struct puffs_usermount *pu, puffs_cookie_t opc,
465: struct puffs_newinfo *pni, const struct puffs_cn *pcn,
466: const struct vattr *vap)
1.1 pooka 467: {
468: struct componentname *cn;
1.14 ! pooka 469: struct vattr *va_x;
1.1 pooka 470: struct vnode *vp;
471: int rv;
472:
1.14 ! pooka 473: DOCOMPAT(vap, va_x);
! 474:
1.1 pooka 475: cn = makecn(pcn);
476: VLE(opc);
477: rump_vp_incref(opc);
1.14 ! pooka 478: rv = RUMP_VOP_MKNOD(opc, &vp, cn, va_x);
1.1 pooka 479: AUL(opc);
480: freecn(cn, 0);
481: if (rv == 0) {
482: VUL(vp);
483: puffs_newinfo_setcookie(pni, vp);
484: }
485:
1.14 ! pooka 486: UNDOCOMPAT(va_x);
! 487:
1.1 pooka 488: return rv;
489: }
490:
491: /*ARGSUSED*/
492: int
1.3 pooka 493: p2k_node_open(struct puffs_usermount *pu, puffs_cookie_t opc, int mode,
1.1 pooka 494: const struct puffs_cred *pcr)
495: {
496: kauth_cred_t cred;
497: int rv;
498:
499: cred = cred_create(pcr);
500: VLE(opc);
501: rv = RUMP_VOP_OPEN(opc, mode, cred);
502: VUL(opc);
503: cred_destroy(cred);
504:
505: return rv;
506: }
507:
508: /*ARGSUSED*/
509: int
1.3 pooka 510: p2k_node_close(struct puffs_usermount *pu, puffs_cookie_t opc, int flags,
1.1 pooka 511: const struct puffs_cred *pcr)
512: {
513: kauth_cred_t cred;
514:
515: cred = cred_create(pcr);
516: VLE(opc);
517: RUMP_VOP_CLOSE(opc, flags, cred);
518: VUL(opc);
519: cred_destroy(cred);
520:
521: return 0;
522: }
523:
524: /*ARGSUSED*/
525: int
1.3 pooka 526: p2k_node_access(struct puffs_usermount *pu, puffs_cookie_t opc, int mode,
1.1 pooka 527: const struct puffs_cred *pcr)
528: {
529: kauth_cred_t cred;
530: int rv;
531:
532: cred = cred_create(pcr);
533: VLE(opc);
534: rv = RUMP_VOP_ACCESS(opc, mode, cred);
535: VUL(opc);
536: cred_destroy(cred);
537:
538: return rv;
539: }
540:
541: /*ARGSUSED*/
542: int
1.3 pooka 543: p2k_node_getattr(struct puffs_usermount *pu, puffs_cookie_t opc,
544: struct vattr *vap, const struct puffs_cred *pcr)
1.1 pooka 545: {
546: kauth_cred_t cred;
1.14 ! pooka 547: struct vattr *va_x;
1.1 pooka 548: int rv;
549:
1.14 ! pooka 550: if (needcompat()) {
! 551: va_x = rump_vattr_init();
! 552: } else {
! 553: va_x = vap;
! 554: }
! 555:
1.1 pooka 556: cred = cred_create(pcr);
557: VLE(opc);
1.14 ! pooka 558: rv = RUMP_VOP_GETATTR(opc, va_x, cred);
1.1 pooka 559: VUL(opc);
560: cred_destroy(cred);
561:
1.14 ! pooka 562: if (needcompat()) {
! 563: rump_vattr_to_vattr50(va_x, vap);
! 564: rump_vattr_free(va_x);
! 565: }
! 566:
1.1 pooka 567: return rv;
568: }
569:
570: /*ARGSUSED*/
571: int
1.3 pooka 572: p2k_node_setattr(struct puffs_usermount *pu, puffs_cookie_t opc,
573: const struct vattr *vap, const struct puffs_cred *pcr)
1.1 pooka 574: {
575: kauth_cred_t cred;
1.14 ! pooka 576: struct vattr *va_x;
1.1 pooka 577: int rv;
578:
1.14 ! pooka 579: DOCOMPAT(vap, va_x);
! 580:
1.1 pooka 581: cred = cred_create(pcr);
582: VLE(opc);
1.14 ! pooka 583: rv = RUMP_VOP_SETATTR(opc, va_x, cred);
1.1 pooka 584: VUL(opc);
585: cred_destroy(cred);
586:
1.14 ! pooka 587: UNDOCOMPAT(va_x);
! 588:
1.1 pooka 589: return rv;
590: }
591:
592: /*ARGSUSED*/
593: int
1.3 pooka 594: p2k_node_fsync(struct puffs_usermount *pu, puffs_cookie_t opc,
1.1 pooka 595: const struct puffs_cred *pcr, int flags, off_t offlo, off_t offhi)
596: {
597: kauth_cred_t cred;
598: int rv;
599:
600: cred = cred_create(pcr);
601: VLE(opc);
602: rv = RUMP_VOP_FSYNC(opc, cred, flags, offlo, offhi);
603: VUL(opc);
604: cred_destroy(cred);
605:
606: return rv;
607: }
608:
609: /*ARGSUSED*/
610: int
1.3 pooka 611: p2k_node_mmap(struct puffs_usermount *pu, puffs_cookie_t opc, vm_prot_t flags,
1.1 pooka 612: const struct puffs_cred *pcr)
613: {
614: kauth_cred_t cred;
615: int rv;
616:
617: cred = cred_create(pcr);
618: rv = RUMP_VOP_MMAP(opc, flags, cred);
619: cred_destroy(cred);
620:
621: return rv;
622: }
623:
624: /*ARGSUSED*/
625: int
1.3 pooka 626: p2k_node_seek(struct puffs_usermount *pu, puffs_cookie_t opc,
627: off_t oldoff, off_t newoff, const struct puffs_cred *pcr)
1.1 pooka 628: {
629: kauth_cred_t cred;
630: int rv;
631:
632: cred = cred_create(pcr);
633: VLE(opc);
634: rv = RUMP_VOP_SEEK(opc, oldoff, newoff, cred);
635: VUL(opc);
636: cred_destroy(cred);
637:
638: return rv;
639: }
640:
641: /*ARGSUSED*/
642: int
1.3 pooka 643: p2k_node_remove(struct puffs_usermount *pu, puffs_cookie_t opc,
644: puffs_cookie_t targ, const struct puffs_cn *pcn)
1.1 pooka 645: {
646: struct componentname *cn;
647: int rv;
648:
649: cn = makecn(pcn);
650: VLE(opc);
651: rump_vp_incref(opc);
652: VLE(targ);
653: rump_vp_incref(targ);
654: rv = RUMP_VOP_REMOVE(opc, targ, cn);
655: AUL(opc);
656: AUL(targ);
657: freecn(cn, 0);
658:
659: return rv;
660: }
661:
662: /*ARGSUSED*/
663: int
1.3 pooka 664: p2k_node_link(struct puffs_usermount *pu, puffs_cookie_t opc,
665: puffs_cookie_t targ, const struct puffs_cn *pcn)
1.1 pooka 666: {
667: struct componentname *cn;
668: int rv;
669:
670: cn = makecn(pcn);
671: VLE(opc);
672: rump_vp_incref(opc);
673: rv = RUMP_VOP_LINK(opc, targ, cn);
674: freecn(cn, 0);
675:
676: return rv;
677: }
678:
679: /*ARGSUSED*/
680: int
1.3 pooka 681: p2k_node_rename(struct puffs_usermount *pu,
682: puffs_cookie_t src_dir, puffs_cookie_t src,
683: const struct puffs_cn *pcn_src,
684: puffs_cookie_t targ_dir, puffs_cookie_t targ,
1.1 pooka 685: const struct puffs_cn *pcn_targ)
686: {
687: struct componentname *cn_src, *cn_targ;
688: int rv;
689:
690: cn_src = makecn(pcn_src);
691: cn_targ = makecn(pcn_targ);
692: rump_vp_incref(src_dir);
693: rump_vp_incref(src);
694: VLE(targ_dir);
695: rump_vp_incref(targ_dir);
696: if (targ) {
697: VLE(targ);
698: rump_vp_incref(targ);
699: }
700: rv = RUMP_VOP_RENAME(src_dir, src, cn_src, targ_dir, targ, cn_targ);
701: AUL(targ_dir);
702: if (targ)
703: AUL(targ);
704: freecn(cn_src, 0);
705: freecn(cn_targ, 0);
706:
707: return rv;
708: }
709:
710: /*ARGSUSED*/
711: int
1.3 pooka 712: p2k_node_mkdir(struct puffs_usermount *pu, puffs_cookie_t opc,
713: struct puffs_newinfo *pni, const struct puffs_cn *pcn,
714: const struct vattr *vap)
1.1 pooka 715: {
716: struct componentname *cn;
1.14 ! pooka 717: struct vattr *va_x;
1.1 pooka 718: struct vnode *vp;
719: int rv;
720:
1.14 ! pooka 721: DOCOMPAT(vap, va_x);
! 722:
1.1 pooka 723: cn = makecn(pcn);
724: VLE(opc);
725: rump_vp_incref(opc);
1.14 ! pooka 726: rv = RUMP_VOP_MKDIR(opc, &vp, cn, va_x);
1.1 pooka 727: AUL(opc);
728: freecn(cn, 0);
729: if (rv == 0) {
730: VUL(vp);
731: puffs_newinfo_setcookie(pni, vp);
732: }
733:
1.14 ! pooka 734: UNDOCOMPAT(va_x);
! 735:
1.1 pooka 736: return rv;
737: }
738:
739: /*ARGSUSED*/
740: int
1.3 pooka 741: p2k_node_rmdir(struct puffs_usermount *pu, puffs_cookie_t opc,
742: puffs_cookie_t targ, const struct puffs_cn *pcn)
1.1 pooka 743: {
744: struct componentname *cn;
745: int rv;
746:
747: cn = makecn(pcn);
748: VLE(opc);
749: rump_vp_incref(opc);
750: VLE(targ);
751: rump_vp_incref(targ);
752: rv = RUMP_VOP_RMDIR(opc, targ, cn);
753: AUL(targ);
754: AUL(opc);
755: freecn(cn, 0);
756:
757: return rv;
758: }
759:
760: /*ARGSUSED*/
761: int
1.3 pooka 762: p2k_node_symlink(struct puffs_usermount *pu, puffs_cookie_t opc,
1.1 pooka 763: struct puffs_newinfo *pni, const struct puffs_cn *pcn_src,
764: const struct vattr *vap, const char *link_target)
765: {
766: struct componentname *cn;
1.14 ! pooka 767: struct vattr *va_x;
1.1 pooka 768: struct vnode *vp;
769: int rv;
770:
1.14 ! pooka 771: DOCOMPAT(vap, va_x);
! 772:
1.1 pooka 773: cn = makecn(pcn_src);
774: VLE(opc);
775: rump_vp_incref(opc);
1.14 ! pooka 776: rv = RUMP_VOP_SYMLINK(opc, &vp, cn, va_x, __UNCONST(link_target));
1.1 pooka 777: AUL(opc);
778: freecn(cn, 0);
779: if (rv == 0) {
780: VUL(vp);
781: puffs_newinfo_setcookie(pni, vp);
782: }
783:
1.14 ! pooka 784: UNDOCOMPAT(va_x);
! 785:
1.1 pooka 786: return rv;
787: }
788:
789: /*ARGSUSED*/
790: int
1.3 pooka 791: p2k_node_readdir(struct puffs_usermount *pu, puffs_cookie_t opc,
792: struct dirent *dent, off_t *readoff, size_t *reslen,
793: const struct puffs_cred *pcr, int *eofflag,
794: off_t *cookies, size_t *ncookies)
1.1 pooka 795: {
796: kauth_cred_t cred;
797: struct uio *uio;
798: off_t *vop_cookies;
799: int vop_ncookies;
800: int rv;
801:
802: cred = cred_create(pcr);
803: uio = rump_uio_setup(dent, *reslen, *readoff, RUMPUIO_READ);
804: VLS(opc);
805: if (cookies) {
806: rv = RUMP_VOP_READDIR(opc, uio, cred, eofflag,
807: &vop_cookies, &vop_ncookies);
808: memcpy(cookies, vop_cookies, vop_ncookies * sizeof(*cookies));
809: *ncookies = vop_ncookies;
810: free(vop_cookies);
811: } else {
812: rv = RUMP_VOP_READDIR(opc, uio, cred, eofflag, NULL, NULL);
813: }
814: VUL(opc);
815: if (rv == 0) {
816: *reslen = rump_uio_getresid(uio);
817: *readoff = rump_uio_getoff(uio);
818: }
819: rump_uio_free(uio);
820: cred_destroy(cred);
821:
822: return rv;
823: }
824:
825: /*ARGSUSED*/
826: int
1.3 pooka 827: p2k_node_readlink(struct puffs_usermount *pu, puffs_cookie_t opc,
1.1 pooka 828: const struct puffs_cred *pcr, char *linkname, size_t *linklen)
829: {
830: kauth_cred_t cred;
831: struct uio *uio;
832: int rv;
833:
834: cred = cred_create(pcr);
835: uio = rump_uio_setup(linkname, *linklen, 0, RUMPUIO_READ);
836: VLE(opc);
837: rv = RUMP_VOP_READLINK(opc, uio, cred);
838: VUL(opc);
839: *linklen -= rump_uio_free(uio);
840: cred_destroy(cred);
841:
842: return rv;
843: }
844:
845: /*ARGSUSED*/
846: int
1.3 pooka 847: p2k_node_read(struct puffs_usermount *pu, puffs_cookie_t opc,
1.1 pooka 848: uint8_t *buf, off_t offset, size_t *resid,
849: const struct puffs_cred *pcr, int ioflag)
850: {
851: kauth_cred_t cred;
852: struct uio *uio;
853: int rv;
854:
855: cred = cred_create(pcr);
856: uio = rump_uio_setup(buf, *resid, offset, RUMPUIO_READ);
857: VLS(opc);
858: rv = RUMP_VOP_READ(opc, uio, ioflag, cred);
859: VUL(opc);
860: *resid = rump_uio_free(uio);
861: cred_destroy(cred);
862:
863: return rv;
864: }
865:
866: /*ARGSUSED*/
867: int
1.3 pooka 868: p2k_node_write(struct puffs_usermount *pu, puffs_cookie_t opc,
1.1 pooka 869: uint8_t *buf, off_t offset, size_t *resid,
870: const struct puffs_cred *pcr, int ioflag)
871: {
872: kauth_cred_t cred;
873: struct uio *uio;
874: int rv;
875:
876: cred = cred_create(pcr);
877: uio = rump_uio_setup(buf, *resid, offset, RUMPUIO_WRITE);
878: VLE(opc);
879: rv = RUMP_VOP_WRITE(opc, uio, ioflag, cred);
880: VUL(opc);
881: *resid = rump_uio_free(uio);
882: cred_destroy(cred);
883:
884: return rv;
885: }
886:
887: int
1.3 pooka 888: p2k_node_inactive(struct puffs_usermount *pu, puffs_cookie_t opc)
1.1 pooka 889: {
890: struct vnode *vp = opc;
891: bool recycle;
892: int rv;
893:
894: rump_vp_interlock(vp);
895: (void) RUMP_VOP_PUTPAGES(vp, 0, 0, PGO_ALLPAGES);
896: VLE(vp);
897: rv = RUMP_VOP_INACTIVE(vp, &recycle);
898: if (recycle)
899: puffs_setback(puffs_cc_getcc(pu), PUFFS_SETBACK_NOREF_N1);
900:
901: return rv;
902: }
903:
904: /*ARGSUSED*/
905: int
1.3 pooka 906: p2k_node_reclaim(struct puffs_usermount *pu, puffs_croissant_t opc)
1.1 pooka 907: {
908:
909: rump_vp_recycle_nokidding(opc);
910: return 0;
911: }
CVSweb <webmaster@jp.NetBSD.org>