1 /* $NetBSD: puffs_subr.c,v 1.66 2008/11/16 19:34:30 pooka Exp $ */
4 * Copyright (c) 2006, 2007 Antti Kantee. All Rights Reserved.
6 * Development of this software was supported by the
7 * Ulla Tuominen Foundation and the Finnish Cultural Foundation.
9 * Redistribution and use in source and binary forms, with or without
10 * modification, are permitted provided that the following conditions
12 * 1. Redistributions of source code must retain the above copyright
13 * notice, this list of conditions and the following disclaimer.
14 * 2. Redistributions in binary form must reproduce the above copyright
15 * notice, this list of conditions and the following disclaimer in the
16 * documentation and/or other materials provided with the distribution.
18 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
19 * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
20 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
21 * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
22 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
23 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
24 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
25 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
26 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
27 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31 #include <sys/param.h>
33 #include <sys/malloc.h>
34 #include <sys/kernel.h>
35 #include <sys/mount.h>
36 #include <sys/namei.h>
40 #include <vfs/puffs/puffs_msgif.h>
41 #include <vfs/puffs/puffs_sys.h>
43 MALLOC_DEFINE(M_PUFFS
, "puffs", "PUFFS");
50 puffs_makecn(struct puffs_kcn
*pkcn
, struct puffs_kcred
*pkcr
,
51 const struct namecache
*ncp
, struct ucred
*cred
)
53 KKASSERT(ncp
->nc_nlen
< sizeof(pkcn
->pkcn_name
));
54 pkcn
->pkcn_namelen
= ncp
->nc_nlen
;
55 strlcpy(pkcn
->pkcn_name
, ncp
->nc_name
, sizeof(pkcn
->pkcn_name
));
57 puffs_credcvt(pkcr
, cred
);
61 * Convert given credentials to struct puffs_kcred for userspace.
64 puffs_credcvt(struct puffs_kcred
*pkcr
, struct ucred
*cred
)
67 memset(pkcr
, 0, sizeof(struct puffs_kcred
));
69 if (cred
== NOCRED
|| cred
== FSCRED
) {
70 pkcr
->pkcr_type
= PUFFCRED_TYPE_INTERNAL
;
72 pkcr
->pkcr_internal
= PUFFCRED_CRED_NOCRED
;
74 pkcr
->pkcr_internal
= PUFFCRED_CRED_FSCRED
;
76 pkcr
->pkcr_type
= PUFFCRED_TYPE_UUC
;
77 cru2x(cred
, &pkcr
->pkcr_uuc
);
82 puffs_parkdone_asyncbioread(struct puffs_mount
*pmp
,
83 struct puffs_req
*preq
, void *arg
)
85 struct puffs_vnmsg_read
*read_msg
= (void *)preq
;
89 DPRINTF(("%s\n", __func__
));
91 bp
->b_error
= checkerr(pmp
, preq
->preq_rv
, __func__
);
92 if (bp
->b_error
== 0) {
93 if (read_msg
->pvnr_resid
> bp
->b_bcount
) {
94 puffs_senderr(pmp
, PUFFS_ERR_READ
, E2BIG
,
95 "resid grew", preq
->preq_cookie
);
98 moved
= bp
->b_bcount
- read_msg
->pvnr_resid
;
99 bp
->b_resid
= read_msg
->pvnr_resid
;
101 memcpy(bp
->b_data
, read_msg
->pvnr_data
, moved
);
109 puffs_parkdone_asyncbiowrite(struct puffs_mount
*pmp
,
110 struct puffs_req
*preq
, void *arg
)
112 struct puffs_vnmsg_write
*write_msg
= (void *)preq
;
113 struct buf
*bp
= arg
;
115 DPRINTF(("%s\n", __func__
));
117 bp
->b_error
= checkerr(pmp
, preq
->preq_rv
, __func__
);
118 if (bp
->b_error
== 0) {
119 if (write_msg
->pvnr_resid
> bp
->b_bcount
) {
120 puffs_senderr(pmp
, PUFFS_ERR_WRITE
, E2BIG
,
121 "resid grew", preq
->preq_cookie
);
124 bp
->b_resid
= write_msg
->pvnr_resid
;
131 /* XXX: userspace can leak kernel resources */
133 puffs_parkdone_poll(struct puffs_mount
*pmp
, struct puffs_req
*preq
, void *arg
)
135 struct puffs_vnmsg_poll
*poll_msg
= (void *)preq
;
136 struct puffs_node
*pn
= arg
;
139 error
= checkerr(pmp
, preq
->preq_rv
, __func__
);
141 revents
= poll_msg
->pvnr_events
;
145 lockmgr(&pn
->pn_mtx
, LK_EXCLUSIVE
);
146 pn
->pn_revents
|= revents
;
147 lockmgr(&pn
->pn_mtx
, LK_RELEASE
);
150 selnotify(&pn
->pn_sel
, revents
, 0);
153 puffs_releasenode(pn
);
157 puffs_mp_reference(struct puffs_mount
*pmp
)
160 KKASSERT(lockstatus(&pmp
->pmp_lock
, curthread
) == LK_EXCLUSIVE
);
165 puffs_mp_release(struct puffs_mount
*pmp
)
168 KKASSERT(lockstatus(&pmp
->pmp_lock
, curthread
) == LK_EXCLUSIVE
);
169 if (--pmp
->pmp_refcount
== 0)
170 cv_broadcast(&pmp
->pmp_refcount_cv
);
174 puffs_senderr(struct puffs_mount
*pmp
, int type
, int error
,
175 const char *str
, puffs_cookie_t ck
)
177 struct puffs_msgpark
*park
;
178 struct puffs_error
*perr
;
180 puffs_msgmem_alloc(sizeof(struct puffs_error
), &park
, (void *)&perr
, 1);
181 puffs_msg_setfaf(park
);
182 puffs_msg_setinfo(park
, PUFFSOP_ERROR
, type
, ck
);
184 perr
->perr_error
= error
;
185 strlcpy(perr
->perr_str
, str
, sizeof(perr
->perr_str
));
187 puffs_msg_enqueue(pmp
, park
);
188 puffs_msgmem_release(park
);