xref: /netbsd-src/sys/fs/puffs/puffs_subr.c (revision 7fa608457b817eca6e0977b37f758ae064f3c99c)
1 /*	$NetBSD: puffs_subr.c,v 1.57 2007/10/11 19:41:14 pooka Exp $	*/
2 
3 /*
4  * Copyright (c) 2006, 2007  Antti Kantee.  All Rights Reserved.
5  *
6  * Development of this software was supported by the
7  * Ulla Tuominen Foundation and the Finnish Cultural Foundation.
8  *
9  * Redistribution and use in source and binary forms, with or without
10  * modification, are permitted provided that the following conditions
11  * are met:
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.
17  *
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
28  * SUCH DAMAGE.
29  */
30 
31 #include <sys/cdefs.h>
32 __KERNEL_RCSID(0, "$NetBSD: puffs_subr.c,v 1.57 2007/10/11 19:41:14 pooka Exp $");
33 
34 #include <sys/param.h>
35 #include <sys/malloc.h>
36 #include <sys/mount.h>
37 #include <sys/namei.h>
38 #include <sys/poll.h>
39 #include <sys/proc.h>
40 
41 #include <fs/puffs/puffs_msgif.h>
42 #include <fs/puffs/puffs_sys.h>
43 
44 #ifdef PUFFSDEBUG
45 int puffsdebug;
46 #endif
47 
48 void
49 puffs_makecn(struct puffs_kcn *pkcn, struct puffs_kcred *pkcr,
50 	struct puffs_kcid *pkcid, const struct componentname *cn, int full)
51 {
52 
53 	pkcn->pkcn_nameiop = cn->cn_nameiop;
54 	pkcn->pkcn_flags = cn->cn_flags;
55 	puffs_cidcvt(pkcid, cn->cn_lwp);
56 
57 	if (full) {
58 		(void)strcpy(pkcn->pkcn_name, cn->cn_nameptr);
59 	} else {
60 		(void)memcpy(pkcn->pkcn_name, cn->cn_nameptr, cn->cn_namelen);
61 		pkcn->pkcn_name[cn->cn_namelen] = '\0';
62 	}
63 	pkcn->pkcn_namelen = cn->cn_namelen;
64 	pkcn->pkcn_consume = 0;
65 
66 	puffs_credcvt(pkcr, cn->cn_cred);
67 }
68 
69 /*
70  * Convert given credentials to struct puffs_kcred for userspace.
71  */
72 void
73 puffs_credcvt(struct puffs_kcred *pkcr, const kauth_cred_t cred)
74 {
75 
76 	memset(pkcr, 0, sizeof(struct puffs_kcred));
77 
78 	if (cred == NOCRED || cred == FSCRED) {
79 		pkcr->pkcr_type = PUFFCRED_TYPE_INTERNAL;
80 		if (cred == NOCRED)
81 			pkcr->pkcr_internal = PUFFCRED_CRED_NOCRED;
82 		if (cred == FSCRED)
83 			pkcr->pkcr_internal = PUFFCRED_CRED_FSCRED;
84  	} else {
85 		pkcr->pkcr_type = PUFFCRED_TYPE_UUC;
86 		kauth_cred_to_uucred(&pkcr->pkcr_uuc, cred);
87 	}
88 }
89 
90 void
91 puffs_cidcvt(struct puffs_kcid *pkcid, const struct lwp *l)
92 {
93 
94 	if (l) {
95 		pkcid->pkcid_type = PUFFCID_TYPE_REAL;
96 		pkcid->pkcid_pid = l->l_proc->p_pid;
97 		pkcid->pkcid_lwpid = l->l_lid;
98 	} else {
99 		pkcid->pkcid_type = PUFFCID_TYPE_FAKE;
100 		pkcid->pkcid_pid = 0;
101 		pkcid->pkcid_lwpid = 0;
102 	}
103 }
104 
105 void
106 puffs_parkdone_asyncbioread(struct puffs_mount *pmp,
107 	struct puffs_req *preq, void *arg)
108 {
109 	struct puffs_vnmsg_read *read_msg = (void *)preq;
110 	struct buf *bp = arg;
111 	size_t moved;
112 
113 	bp->b_error = checkerr(pmp, preq->preq_rv, __func__);
114 	if (bp->b_error == 0) {
115 		moved = bp->b_bcount - read_msg->pvnr_resid;
116 		bp->b_resid = read_msg->pvnr_resid;
117 
118 		memcpy(bp->b_data, read_msg->pvnr_data, moved);
119 	}
120 
121 	biodone(bp);
122 }
123 
124 /* XXX: userspace can leak kernel resources */
125 void
126 puffs_parkdone_poll(struct puffs_mount *pmp, struct puffs_req *preq, void *arg)
127 {
128 	struct puffs_vnmsg_poll *poll_msg = (void *)preq;
129 	struct puffs_node *pn = arg;
130 	int revents, error;
131 
132 	error = checkerr(pmp, preq->preq_rv, __func__);
133 	if (error)
134 		revents = poll_msg->pvnr_events;
135 	else
136 		revents = POLLERR;
137 
138 	mutex_enter(&pn->pn_mtx);
139 	pn->pn_revents |= revents;
140 	mutex_exit(&pn->pn_mtx);
141 
142 	selnotify(&pn->pn_sel, 0);
143 
144 	puffs_releasenode(pn);
145 }
146 
147 void
148 puffs_mp_reference(struct puffs_mount *pmp)
149 {
150 
151 	KASSERT(mutex_owned(&pmp->pmp_lock));
152 	pmp->pmp_refcount++;
153 }
154 
155 void
156 puffs_mp_release(struct puffs_mount *pmp)
157 {
158 
159 	KASSERT(mutex_owned(&pmp->pmp_lock));
160 	if (--pmp->pmp_refcount == 0)
161 		cv_broadcast(&pmp->pmp_refcount_cv);
162 }
163 
164 void
165 puffs_gop_size(struct vnode *vp, off_t size, off_t *eobp,
166 	int flags)
167 {
168 
169 	*eobp = size;
170 }
171 
172 void
173 puffs_gop_markupdate(struct vnode *vp, int flags)
174 {
175 	int uflags = 0;
176 
177 	if (flags & GOP_UPDATE_ACCESSED)
178 		uflags |= PUFFS_UPDATEATIME;
179 	if (flags & GOP_UPDATE_MODIFIED)
180 		uflags |= PUFFS_UPDATEMTIME;
181 
182 	puffs_updatenode(vp, uflags);
183 }
184