1 /* $NetBSD: puffs_compat.c,v 1.4 2015/04/22 17:07:24 pooka Exp $ */
4 * Copyright (c) 2010 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 * This file handles puffs PDUs so that they are compatible between
30 * 32bit<->64bit time_t/dev_t. It enables running a -current kernel
31 * against a 5.0 userland (assuming the protocol otherwise matches!).
34 #include <sys/cdefs.h>
35 __KERNEL_RCSID(0, "$NetBSD: puffs_compat.c,v 1.4 2015/04/22 17:07:24 pooka Exp $");
37 #include <sys/param.h>
38 #include <sys/atomic.h>
40 #include <sys/kthread.h>
42 #include <sys/mount.h>
43 #include <sys/namei.h>
45 #include <sys/vnode.h>
46 #include <sys/atomic.h>
48 #include <dev/putter/putter_sys.h>
50 #include <fs/puffs/puffs_msgif.h>
51 #include <fs/puffs/puffs_sys.h>
53 #include <compat/sys/time.h>
68 struct timespec50 va_atime
;
69 struct timespec50 va_mtime
;
70 struct timespec50 va_ctime
;
71 struct timespec50 va_birthtime
;
81 struct puffs50_vfsmsg_fhtonode
{
82 struct puffs_req pvfsr_pr
;
84 void *pvfsr_fhcookie
; /* IN */
85 enum vtype pvfsr_vtype
; /* IN */
86 voff_t pvfsr_size
; /* IN */
87 uint32_t pvfsr_rdev
; /* IN */
89 size_t pvfsr_dsize
; /* OUT */
90 uint8_t pvfsr_data
[0] /* OUT, XXX */
91 __aligned(ALIGNBYTES
+1);
94 struct puffs50_vnmsg_lookup
{
95 struct puffs_req pvn_pr
;
97 struct puffs_kcn pvnr_cn
; /* OUT */
98 struct puffs_kcred pvnr_cn_cred
; /* OUT */
100 puffs_cookie_t pvnr_newnode
; /* IN */
101 enum vtype pvnr_vtype
; /* IN */
102 voff_t pvnr_size
; /* IN */
103 uint32_t pvnr_rdev
; /* IN */
106 struct puffs50_vnmsg_create
{
107 struct puffs_req pvn_pr
;
109 struct puffs_kcn pvnr_cn
; /* OUT */
110 struct puffs_kcred pvnr_cn_cred
; /* OUT */
112 struct vattr50 pvnr_va
; /* OUT */
113 puffs_cookie_t pvnr_newnode
; /* IN */
116 struct puffs50_vnmsg_mknod
{
117 struct puffs_req pvn_pr
;
119 struct puffs_kcn pvnr_cn
; /* OUT */
120 struct puffs_kcred pvnr_cn_cred
; /* OUT */
122 struct vattr50 pvnr_va
; /* OUT */
123 puffs_cookie_t pvnr_newnode
; /* IN */
126 #define puffs50_vnmsg_setattr puffs50_vnmsg_setgetattr
127 #define puffs50_vnmsg_getattr puffs50_vnmsg_setgetattr
128 struct puffs50_vnmsg_setgetattr
{
129 struct puffs_req pvn_pr
;
131 struct puffs_kcred pvnr_cred
; /* OUT */
132 struct vattr50 pvnr_va
; /* IN/OUT (op depend) */
135 struct puffs50_vnmsg_mkdir
{
136 struct puffs_req pvn_pr
;
138 struct puffs_kcn pvnr_cn
; /* OUT */
139 struct puffs_kcred pvnr_cn_cred
; /* OUT */
141 struct vattr50 pvnr_va
; /* OUT */
142 puffs_cookie_t pvnr_newnode
; /* IN */
145 struct puffs50_vnmsg_symlink
{
146 struct puffs_req pvn_pr
;
148 struct puffs_kcn pvnr_cn
; /* OUT */
149 struct puffs_kcred pvnr_cn_cred
; /* OUT */
151 struct vattr50 pvnr_va
; /* OUT */
152 puffs_cookie_t pvnr_newnode
; /* IN */
153 char pvnr_link
[MAXPATHLEN
]; /* OUT */
157 * vattr translation routines
162 vattr_to_50(const struct vattr
*va
, struct vattr50
*va50
)
165 va50
->va_type
= va
->va_type
;
166 va50
->va_mode
= va
->va_mode
;
167 va50
->va_nlink
= va
->va_nlink
;
168 va50
->va_uid
= va
->va_uid
;
169 va50
->va_gid
= va
->va_gid
;
170 va50
->va_fsid
= (uint64_t)va
->va_fsid
;
171 va50
->va_fileid
= va
->va_fileid
;
172 va50
->va_size
= va
->va_size
;
173 va50
->va_blocksize
= va
->va_blocksize
;
174 timespec_to_timespec50(&va
->va_atime
, &va50
->va_atime
);
175 timespec_to_timespec50(&va
->va_ctime
, &va50
->va_ctime
);
176 timespec_to_timespec50(&va
->va_mtime
, &va50
->va_mtime
);
177 timespec_to_timespec50(&va
->va_birthtime
, &va50
->va_birthtime
);
178 va50
->va_gen
= va
->va_gen
;
179 va50
->va_flags
= va
->va_flags
;
180 va50
->va_rdev
= (int32_t)va
->va_rdev
;
181 va50
->va_bytes
= va
->va_bytes
;
182 va50
->va_filerev
= va
->va_filerev
;
183 va50
->va_vaflags
= va
->va_flags
;
187 vattr_from_50(const struct vattr50
*va50
, struct vattr
*va
)
190 va
->va_type
= va50
->va_type
;
191 va
->va_mode
= va50
->va_mode
;
192 va
->va_nlink
= va50
->va_nlink
;
193 va
->va_uid
= va50
->va_uid
;
194 va
->va_gid
= va50
->va_gid
;
195 va
->va_fsid
= (uint32_t)va50
->va_fsid
;
196 va
->va_fileid
= va50
->va_fileid
;
197 va
->va_size
= va50
->va_size
;
198 va
->va_blocksize
= va50
->va_blocksize
;
199 timespec50_to_timespec(&va50
->va_atime
, &va
->va_atime
);
200 timespec50_to_timespec(&va50
->va_ctime
, &va
->va_ctime
);
201 timespec50_to_timespec(&va50
->va_mtime
, &va
->va_mtime
);
202 timespec50_to_timespec(&va50
->va_birthtime
, &va
->va_birthtime
);
203 va
->va_gen
= va50
->va_gen
;
204 va
->va_flags
= va50
->va_flags
;
205 va
->va_rdev
= (uint32_t)va50
->va_rdev
;
206 va
->va_bytes
= va50
->va_bytes
;
207 va
->va_filerev
= va50
->va_filerev
;
208 va
->va_vaflags
= va50
->va_flags
;
210 #endif /* COMPAT_50 */
213 * XXX: cannot assert that sleeping is possible
214 * (this always a valid assumption for now)
216 #define INIT(name, extra) \
217 struct puffs50_##name *cmsg; \
218 struct puffs_##name *omsg; \
219 creq =kmem_zalloc(sizeof(struct puffs50_##name)+extra,KM_SLEEP);\
220 cmsg = (struct puffs50_##name *)creq; \
221 omsg = (struct puffs_##name *)oreq; \
222 delta = sizeof(struct puffs50_##name)-sizeof(struct puffs_##name);
223 #define ASSIGN(field) \
224 cmsg->field = omsg->field;
227 puffs_compat_outgoing(struct puffs_req
*oreq
,
228 struct puffs_req
**creqp
, ssize_t
*deltap
)
232 struct puffs_req
*creq
= NULL
;
235 if (PUFFSOP_OPCLASS(oreq
->preq_opclass
) == PUFFSOP_VFS
236 && oreq
->preq_optype
== PUFFS_VFS_FHTOVP
) {
237 INIT(vfsmsg_fhtonode
,
238 ((struct puffs_vfsmsg_fhtonode
*)oreq
)->pvfsr_dsize
);
242 memcpy(cmsg
->pvfsr_data
, omsg
->pvfsr_data
, cmsg
->pvfsr_dsize
);
243 } else if (PUFFSOP_OPCLASS(oreq
->preq_opclass
) == PUFFSOP_VN
) {
244 switch (oreq
->preq_optype
) {
245 case PUFFS_VN_LOOKUP
:
247 INIT(vnmsg_lookup
, 0);
251 ASSIGN(pvnr_cn_cred
);
256 case PUFFS_VN_CREATE
:
258 INIT(vnmsg_create
, 0);
262 ASSIGN(pvnr_cn_cred
);
263 vattr_to_50(&omsg
->pvnr_va
, &cmsg
->pvnr_va
);
270 INIT(vnmsg_mknod
, 0);
274 ASSIGN(pvnr_cn_cred
);
275 vattr_to_50(&omsg
->pvnr_va
, &cmsg
->pvnr_va
);
282 INIT(vnmsg_mkdir
, 0);
286 ASSIGN(pvnr_cn_cred
);
287 vattr_to_50(&omsg
->pvnr_va
, &cmsg
->pvnr_va
);
292 case PUFFS_VN_SYMLINK
:
294 INIT(vnmsg_symlink
, 0);
298 ASSIGN(pvnr_cn_cred
);
299 vattr_to_50(&omsg
->pvnr_va
, &cmsg
->pvnr_va
);
300 memcpy(cmsg
->pvnr_link
, omsg
->pvnr_link
,
301 sizeof(cmsg
->pvnr_link
));
306 case PUFFS_VN_SETATTR
:
308 INIT(vnmsg_setattr
, 0);
312 vattr_to_50(&omsg
->pvnr_va
, &cmsg
->pvnr_va
);
316 case PUFFS_VN_GETATTR
:
318 INIT(vnmsg_getattr
, 0);
344 struct puffs50_##name *cmsg = (void *)preq; \
345 struct puffs_##name *omsg = (void *)creq;
346 #define ASSIGN(field) \
347 omsg->field = cmsg->field;
350 puffs_compat_incoming(struct puffs_req
*preq
, struct puffs_req
*creq
)
354 if (PUFFSOP_OPCLASS(preq
->preq_opclass
) == PUFFSOP_VFS
355 && preq
->preq_optype
== PUFFS_VFS_FHTOVP
) {
356 INIT(vfsmsg_fhtonode
);
360 ASSIGN(pvfsr_fhcookie
);
364 } else if (PUFFSOP_OPCLASS(preq
->preq_opclass
) == PUFFSOP_VN
) {
365 switch (preq
->preq_optype
) {
366 case PUFFS_VN_LOOKUP
:
371 ASSIGN(pvnr_newnode
);
379 case PUFFS_VN_CREATE
:
384 ASSIGN(pvnr_newnode
);
394 ASSIGN(pvnr_newnode
);
404 ASSIGN(pvnr_newnode
);
409 case PUFFS_VN_SYMLINK
:
414 ASSIGN(pvnr_newnode
);
419 case PUFFS_VN_SETATTR
:
427 case PUFFS_VN_GETATTR
:
432 vattr_from_50(&cmsg
->pvnr_va
, &omsg
->pvnr_va
);
438 panic("puffs compat ops come in pairs");
441 #endif /* COMPAT_50 */