Home | History | Annotate | Line # | Download | only in puffs
puffs_compat.c revision 1.4.16.2
      1  1.4.16.2  pgoyette /*	$NetBSD: puffs_compat.c,v 1.4.16.2 2018/09/17 11:04:31 pgoyette Exp $	*/
      2       1.1     pooka 
      3       1.1     pooka /*
      4       1.1     pooka  * Copyright (c) 2010 Antti Kantee.  All Rights Reserved.
      5       1.1     pooka  *
      6       1.1     pooka  * Redistribution and use in source and binary forms, with or without
      7       1.1     pooka  * modification, are permitted provided that the following conditions
      8       1.1     pooka  * are met:
      9       1.1     pooka  * 1. Redistributions of source code must retain the above copyright
     10       1.1     pooka  *    notice, this list of conditions and the following disclaimer.
     11       1.1     pooka  * 2. Redistributions in binary form must reproduce the above copyright
     12       1.1     pooka  *    notice, this list of conditions and the following disclaimer in the
     13       1.1     pooka  *    documentation and/or other materials provided with the distribution.
     14       1.1     pooka  *
     15       1.1     pooka  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
     16       1.1     pooka  * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
     17       1.1     pooka  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
     18       1.1     pooka  * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
     19       1.1     pooka  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
     20       1.1     pooka  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
     21       1.1     pooka  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
     22       1.1     pooka  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
     23       1.1     pooka  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
     24       1.1     pooka  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
     25       1.1     pooka  * SUCH DAMAGE.
     26       1.1     pooka  */
     27       1.1     pooka 
     28       1.1     pooka /*
     29       1.1     pooka  * This file handles puffs PDUs so that they are compatible between
     30       1.1     pooka  * 32bit<->64bit time_t/dev_t.  It enables running a -current kernel
     31       1.1     pooka  * against a 5.0 userland (assuming the protocol otherwise matches!).
     32       1.1     pooka  */
     33       1.1     pooka 
     34       1.1     pooka #include <sys/cdefs.h>
     35  1.4.16.2  pgoyette __KERNEL_RCSID(0, "$NetBSD: puffs_compat.c,v 1.4.16.2 2018/09/17 11:04:31 pgoyette Exp $");
     36       1.1     pooka 
     37       1.1     pooka #include <sys/param.h>
     38       1.1     pooka #include <sys/atomic.h>
     39       1.1     pooka #include <sys/kmem.h>
     40       1.1     pooka #include <sys/kthread.h>
     41       1.1     pooka #include <sys/lock.h>
     42       1.1     pooka #include <sys/mount.h>
     43       1.1     pooka #include <sys/namei.h>
     44       1.1     pooka #include <sys/proc.h>
     45       1.1     pooka #include <sys/vnode.h>
     46       1.1     pooka #include <sys/atomic.h>
     47  1.4.16.1  pgoyette #include <sys/compat_stub.h>
     48       1.1     pooka 
     49       1.1     pooka #include <dev/putter/putter_sys.h>
     50       1.1     pooka 
     51       1.1     pooka #include <fs/puffs/puffs_msgif.h>
     52       1.1     pooka #include <fs/puffs/puffs_sys.h>
     53       1.1     pooka 
     54       1.1     pooka #include <compat/sys/time.h>
     55       1.1     pooka 
     56       1.1     pooka /*
     57       1.1     pooka  * compat types
     58       1.1     pooka  */
     59       1.1     pooka struct vattr50 {
     60       1.1     pooka 	enum vtype		va_type;
     61       1.1     pooka 	mode_t			va_mode;
     62       1.1     pooka 	nlink_t			va_nlink;
     63       1.1     pooka 	uid_t			va_uid;
     64       1.1     pooka 	gid_t			va_gid;
     65       1.1     pooka 	uint32_t		va_fsid;
     66       1.1     pooka 	ino_t			va_fileid;
     67       1.1     pooka 	u_quad_t		va_size;
     68       1.1     pooka 	long			va_blocksize;
     69       1.1     pooka 	struct timespec50	va_atime;
     70       1.1     pooka 	struct timespec50	va_mtime;
     71       1.1     pooka 	struct timespec50	va_ctime;
     72       1.1     pooka 	struct timespec50	va_birthtime;
     73       1.1     pooka 	u_long			va_gen;
     74       1.1     pooka 	u_long			va_flags;
     75       1.1     pooka 	uint32_t		va_rdev;
     76       1.1     pooka 	u_quad_t		va_bytes;
     77       1.1     pooka 	u_quad_t		va_filerev;
     78       1.1     pooka 	u_int			va_vaflags;
     79       1.1     pooka 	long			va_spare;
     80       1.1     pooka };
     81       1.1     pooka 
     82       1.1     pooka struct puffs50_vfsmsg_fhtonode {
     83       1.1     pooka 	struct puffs_req	pvfsr_pr;
     84       1.1     pooka 
     85       1.1     pooka 	void			*pvfsr_fhcookie;	/* IN   */
     86       1.1     pooka 	enum vtype		pvfsr_vtype;		/* IN   */
     87       1.1     pooka 	voff_t			pvfsr_size;		/* IN   */
     88       1.1     pooka 	uint32_t		pvfsr_rdev;		/* IN   */
     89       1.1     pooka 
     90       1.1     pooka 	size_t			pvfsr_dsize;		/* OUT */
     91       1.1     pooka 	uint8_t			pvfsr_data[0]		/* OUT, XXX */
     92       1.1     pooka 					__aligned(ALIGNBYTES+1);
     93       1.1     pooka };
     94       1.1     pooka 
     95       1.1     pooka struct puffs50_vnmsg_lookup {
     96       1.1     pooka 	struct puffs_req	pvn_pr;
     97       1.1     pooka 
     98       1.1     pooka 	struct puffs_kcn	pvnr_cn;		/* OUT	*/
     99       1.1     pooka 	struct puffs_kcred	pvnr_cn_cred;		/* OUT	*/
    100       1.1     pooka 
    101       1.1     pooka 	puffs_cookie_t		pvnr_newnode;		/* IN	*/
    102       1.1     pooka 	enum vtype		pvnr_vtype;		/* IN	*/
    103       1.1     pooka 	voff_t			pvnr_size;		/* IN	*/
    104       1.1     pooka 	uint32_t		pvnr_rdev;		/* IN	*/
    105       1.1     pooka };
    106       1.1     pooka 
    107       1.1     pooka struct puffs50_vnmsg_create {
    108       1.1     pooka 	struct puffs_req	pvn_pr;
    109       1.1     pooka 
    110       1.1     pooka 	struct puffs_kcn	pvnr_cn;		/* OUT	*/
    111       1.1     pooka 	struct puffs_kcred	pvnr_cn_cred;		/* OUT	*/
    112       1.1     pooka 
    113       1.1     pooka 	struct vattr50		pvnr_va;		/* OUT	*/
    114       1.1     pooka 	puffs_cookie_t		pvnr_newnode;		/* IN	*/
    115       1.1     pooka };
    116       1.1     pooka 
    117       1.1     pooka struct puffs50_vnmsg_mknod {
    118       1.1     pooka 	struct puffs_req	pvn_pr;
    119       1.1     pooka 
    120       1.1     pooka 	struct puffs_kcn	pvnr_cn;		/* OUT	*/
    121       1.1     pooka 	struct puffs_kcred	pvnr_cn_cred;		/* OUT	*/
    122       1.1     pooka 
    123       1.1     pooka 	struct vattr50		pvnr_va;		/* OUT	*/
    124       1.1     pooka 	puffs_cookie_t		pvnr_newnode;		/* IN	*/
    125       1.1     pooka };
    126       1.1     pooka 
    127       1.1     pooka #define puffs50_vnmsg_setattr puffs50_vnmsg_setgetattr
    128       1.1     pooka #define puffs50_vnmsg_getattr puffs50_vnmsg_setgetattr
    129       1.1     pooka struct puffs50_vnmsg_setgetattr {
    130       1.1     pooka 	struct puffs_req	pvn_pr;
    131       1.1     pooka 
    132       1.1     pooka 	struct puffs_kcred	pvnr_cred;		/* OUT	*/
    133       1.1     pooka 	struct vattr50		pvnr_va;		/* IN/OUT (op depend) */
    134       1.1     pooka };
    135       1.1     pooka 
    136       1.1     pooka struct puffs50_vnmsg_mkdir {
    137       1.1     pooka 	struct puffs_req	pvn_pr;
    138       1.1     pooka 
    139       1.1     pooka 	struct puffs_kcn	pvnr_cn;		/* OUT	*/
    140       1.1     pooka 	struct puffs_kcred	pvnr_cn_cred;		/* OUT	*/
    141       1.1     pooka 
    142       1.1     pooka 	struct vattr50		pvnr_va;		/* OUT	*/
    143       1.1     pooka 	puffs_cookie_t		pvnr_newnode;		/* IN	*/
    144       1.1     pooka };
    145       1.1     pooka 
    146       1.1     pooka struct puffs50_vnmsg_symlink {
    147       1.1     pooka 	struct puffs_req	pvn_pr;
    148       1.1     pooka 
    149       1.1     pooka 	struct puffs_kcn	pvnr_cn;		/* OUT	*/
    150       1.1     pooka 	struct puffs_kcred	pvnr_cn_cred;		/* OUT	*/
    151       1.1     pooka 
    152       1.1     pooka 	struct vattr50		pvnr_va;		/* OUT	*/
    153       1.1     pooka 	puffs_cookie_t		pvnr_newnode;		/* IN	*/
    154       1.1     pooka 	char			pvnr_link[MAXPATHLEN];	/* OUT	*/
    155       1.1     pooka };
    156       1.1     pooka 
    157       1.1     pooka /*
    158       1.1     pooka  * vattr translation routines
    159       1.1     pooka  */
    160       1.1     pooka 
    161       1.1     pooka static void
    162       1.1     pooka vattr_to_50(const struct vattr *va, struct vattr50 *va50)
    163       1.1     pooka {
    164       1.1     pooka 
    165       1.1     pooka 	va50->va_type = va->va_type;
    166       1.1     pooka 	va50->va_mode = va->va_mode;
    167       1.1     pooka 	va50->va_nlink = va->va_nlink;
    168       1.1     pooka 	va50->va_uid = va->va_uid;
    169       1.1     pooka 	va50->va_gid = va->va_gid;
    170       1.1     pooka 	va50->va_fsid = (uint64_t)va->va_fsid;
    171       1.1     pooka 	va50->va_fileid = va->va_fileid;
    172       1.1     pooka 	va50->va_size = va->va_size;
    173       1.1     pooka 	va50->va_blocksize = va->va_blocksize;
    174       1.1     pooka 	timespec_to_timespec50(&va->va_atime, &va50->va_atime);
    175       1.1     pooka 	timespec_to_timespec50(&va->va_ctime, &va50->va_ctime);
    176       1.1     pooka 	timespec_to_timespec50(&va->va_mtime, &va50->va_mtime);
    177       1.1     pooka 	timespec_to_timespec50(&va->va_birthtime, &va50->va_birthtime);
    178       1.1     pooka 	va50->va_gen = va->va_gen;
    179       1.1     pooka 	va50->va_flags = va->va_flags;
    180       1.1     pooka 	va50->va_rdev = (int32_t)va->va_rdev;
    181       1.1     pooka 	va50->va_bytes = va->va_bytes;
    182       1.1     pooka 	va50->va_filerev = va->va_filerev;
    183       1.1     pooka 	va50->va_vaflags = va->va_flags;
    184       1.1     pooka }
    185       1.1     pooka 
    186       1.1     pooka static void
    187       1.1     pooka vattr_from_50(const struct vattr50 *va50, struct vattr *va)
    188       1.1     pooka {
    189       1.1     pooka 
    190       1.1     pooka 	va->va_type = va50->va_type;
    191       1.1     pooka 	va->va_mode = va50->va_mode;
    192       1.1     pooka 	va->va_nlink = va50->va_nlink;
    193       1.1     pooka 	va->va_uid = va50->va_uid;
    194       1.1     pooka 	va->va_gid = va50->va_gid;
    195       1.1     pooka 	va->va_fsid = (uint32_t)va50->va_fsid;
    196       1.1     pooka 	va->va_fileid = va50->va_fileid;
    197       1.1     pooka 	va->va_size = va50->va_size;
    198       1.1     pooka 	va->va_blocksize = va50->va_blocksize;
    199       1.1     pooka 	timespec50_to_timespec(&va50->va_atime, &va->va_atime);
    200       1.1     pooka 	timespec50_to_timespec(&va50->va_ctime, &va->va_ctime);
    201       1.1     pooka 	timespec50_to_timespec(&va50->va_mtime, &va->va_mtime);
    202       1.1     pooka 	timespec50_to_timespec(&va50->va_birthtime, &va->va_birthtime);
    203       1.1     pooka 	va->va_gen = va50->va_gen;
    204       1.1     pooka 	va->va_flags = va50->va_flags;
    205       1.1     pooka 	va->va_rdev = (uint32_t)va50->va_rdev;
    206       1.1     pooka 	va->va_bytes = va50->va_bytes;
    207       1.1     pooka 	va->va_filerev = va50->va_filerev;
    208       1.1     pooka 	va->va_vaflags = va50->va_flags;
    209       1.1     pooka }
    210       1.1     pooka 
    211       1.1     pooka /*
    212       1.1     pooka  * XXX: cannot assert that sleeping is possible
    213       1.1     pooka  * (this always a valid assumption for now)
    214       1.1     pooka  */
    215       1.2     pooka #define INIT(name, extra)						\
    216       1.1     pooka 	struct puffs50_##name *cmsg;					\
    217       1.1     pooka 	struct puffs_##name *omsg;					\
    218       1.2     pooka 	creq =kmem_zalloc(sizeof(struct puffs50_##name)+extra,KM_SLEEP);\
    219       1.1     pooka 	cmsg = (struct puffs50_##name *)creq;				\
    220       1.1     pooka 	omsg = (struct puffs_##name *)oreq;				\
    221       1.1     pooka 	delta = sizeof(struct puffs50_##name)-sizeof(struct puffs_##name);
    222       1.1     pooka #define ASSIGN(field)							\
    223       1.1     pooka 	cmsg->field = omsg->field;
    224       1.1     pooka 
    225  1.4.16.1  pgoyette int
    226       1.1     pooka puffs_compat_outgoing(struct puffs_req *oreq,
    227       1.1     pooka 	struct puffs_req **creqp, ssize_t *deltap)
    228       1.1     pooka {
    229  1.4.16.1  pgoyette 	int rv = ENOSYS;	/* non-zero return ==> false */
    230       1.1     pooka 	struct puffs_req *creq = NULL;
    231       1.1     pooka 	ssize_t delta = 0;
    232       1.1     pooka 
    233       1.2     pooka 	if (PUFFSOP_OPCLASS(oreq->preq_opclass) == PUFFSOP_VFS
    234       1.2     pooka 	    && oreq->preq_optype == PUFFS_VFS_FHTOVP) {
    235       1.2     pooka 		INIT(vfsmsg_fhtonode,
    236       1.2     pooka 		    ((struct puffs_vfsmsg_fhtonode *)oreq)->pvfsr_dsize);
    237       1.1     pooka 
    238       1.1     pooka 		ASSIGN(pvfsr_pr);
    239       1.1     pooka 		ASSIGN(pvfsr_dsize);
    240       1.1     pooka 		memcpy(cmsg->pvfsr_data, omsg->pvfsr_data, cmsg->pvfsr_dsize);
    241       1.1     pooka 	} else if (PUFFSOP_OPCLASS(oreq->preq_opclass) == PUFFSOP_VN) {
    242       1.1     pooka 		switch (oreq->preq_optype) {
    243       1.1     pooka 		case PUFFS_VN_LOOKUP:
    244       1.1     pooka 		{
    245       1.2     pooka 			INIT(vnmsg_lookup, 0);
    246       1.1     pooka 
    247       1.1     pooka 			ASSIGN(pvn_pr);
    248       1.1     pooka 			ASSIGN(pvnr_cn);
    249       1.1     pooka 			ASSIGN(pvnr_cn_cred);
    250       1.1     pooka 
    251       1.1     pooka 			break;
    252       1.1     pooka 		}
    253       1.1     pooka 
    254       1.1     pooka 		case PUFFS_VN_CREATE:
    255       1.1     pooka 		{
    256       1.2     pooka 			INIT(vnmsg_create, 0);
    257       1.1     pooka 
    258       1.1     pooka 			ASSIGN(pvn_pr);
    259       1.1     pooka 			ASSIGN(pvnr_cn);
    260       1.1     pooka 			ASSIGN(pvnr_cn_cred);
    261       1.1     pooka 			vattr_to_50(&omsg->pvnr_va, &cmsg->pvnr_va);
    262       1.1     pooka 
    263       1.1     pooka 			break;
    264       1.1     pooka 		}
    265       1.1     pooka 
    266       1.1     pooka 		case PUFFS_VN_MKNOD:
    267       1.1     pooka 		{
    268       1.2     pooka 			INIT(vnmsg_mknod, 0);
    269       1.1     pooka 
    270       1.1     pooka 			ASSIGN(pvn_pr);
    271       1.1     pooka 			ASSIGN(pvnr_cn);
    272       1.1     pooka 			ASSIGN(pvnr_cn_cred);
    273       1.1     pooka 			vattr_to_50(&omsg->pvnr_va, &cmsg->pvnr_va);
    274       1.1     pooka 
    275       1.1     pooka 			break;
    276       1.1     pooka 		}
    277       1.1     pooka 
    278       1.1     pooka 		case PUFFS_VN_MKDIR:
    279       1.1     pooka 		{
    280       1.2     pooka 			INIT(vnmsg_mkdir, 0);
    281       1.1     pooka 
    282       1.1     pooka 			ASSIGN(pvn_pr);
    283       1.1     pooka 			ASSIGN(pvnr_cn);
    284       1.1     pooka 			ASSIGN(pvnr_cn_cred);
    285       1.1     pooka 			vattr_to_50(&omsg->pvnr_va, &cmsg->pvnr_va);
    286       1.1     pooka 
    287       1.1     pooka 			break;
    288       1.1     pooka 		}
    289       1.1     pooka 
    290       1.1     pooka 		case PUFFS_VN_SYMLINK:
    291       1.1     pooka 		{
    292       1.2     pooka 			INIT(vnmsg_symlink, 0);
    293       1.1     pooka 
    294       1.1     pooka 			ASSIGN(pvn_pr);
    295       1.1     pooka 			ASSIGN(pvnr_cn);
    296       1.1     pooka 			ASSIGN(pvnr_cn_cred);
    297       1.1     pooka 			vattr_to_50(&omsg->pvnr_va, &cmsg->pvnr_va);
    298       1.1     pooka 			memcpy(cmsg->pvnr_link, omsg->pvnr_link,
    299       1.1     pooka 			    sizeof(cmsg->pvnr_link));
    300       1.1     pooka 
    301       1.1     pooka 			break;
    302       1.1     pooka 		}
    303       1.1     pooka 
    304       1.1     pooka 		case PUFFS_VN_SETATTR:
    305       1.1     pooka 		{
    306       1.2     pooka 			INIT(vnmsg_setattr, 0);
    307       1.1     pooka 
    308       1.1     pooka 			ASSIGN(pvn_pr);
    309       1.1     pooka 			ASSIGN(pvnr_cred);
    310       1.1     pooka 			vattr_to_50(&omsg->pvnr_va, &cmsg->pvnr_va);
    311       1.1     pooka 
    312       1.1     pooka 			break;
    313       1.1     pooka 		}
    314       1.1     pooka 		case PUFFS_VN_GETATTR:
    315       1.1     pooka 		{
    316       1.2     pooka 			INIT(vnmsg_getattr, 0);
    317       1.1     pooka 
    318       1.1     pooka 			ASSIGN(pvn_pr);
    319       1.1     pooka 			ASSIGN(pvnr_cred);
    320       1.1     pooka 
    321       1.1     pooka 			break;
    322       1.1     pooka 		}
    323       1.1     pooka 
    324       1.1     pooka 		default:
    325       1.1     pooka 			break;
    326       1.1     pooka 		}
    327       1.1     pooka 	}
    328       1.1     pooka 
    329       1.1     pooka 	if (creq) {
    330       1.1     pooka 		*creqp = creq;
    331       1.1     pooka 		*deltap = delta;
    332  1.4.16.1  pgoyette 		rv = 0;
    333       1.1     pooka 	}
    334       1.1     pooka 
    335       1.1     pooka 	return rv;
    336       1.1     pooka }
    337       1.1     pooka #undef INIT
    338       1.1     pooka #undef ASSIGN
    339       1.1     pooka 
    340       1.1     pooka #define INIT(name)							\
    341       1.1     pooka 	struct puffs50_##name *cmsg = (void *)preq;			\
    342       1.1     pooka 	struct puffs_##name *omsg = (void *)creq;
    343       1.1     pooka #define ASSIGN(field)							\
    344       1.1     pooka 	omsg->field = cmsg->field;
    345       1.1     pooka 
    346  1.4.16.2  pgoyette int
    347       1.1     pooka puffs_compat_incoming(struct puffs_req *preq, struct puffs_req *creq)
    348       1.1     pooka {
    349       1.1     pooka 
    350       1.2     pooka 	if (PUFFSOP_OPCLASS(preq->preq_opclass) == PUFFSOP_VFS
    351       1.2     pooka 	    && preq->preq_optype == PUFFS_VFS_FHTOVP) {
    352       1.1     pooka 		INIT(vfsmsg_fhtonode);
    353       1.1     pooka 
    354       1.1     pooka 		ASSIGN(pvfsr_pr);
    355       1.1     pooka 
    356       1.1     pooka 		ASSIGN(pvfsr_fhcookie);
    357       1.1     pooka 		ASSIGN(pvfsr_vtype);
    358       1.1     pooka 		ASSIGN(pvfsr_size);
    359       1.1     pooka 		ASSIGN(pvfsr_rdev);
    360       1.1     pooka 	} else if (PUFFSOP_OPCLASS(preq->preq_opclass) == PUFFSOP_VN) {
    361       1.1     pooka 		switch (preq->preq_optype) {
    362       1.1     pooka 		case PUFFS_VN_LOOKUP:
    363       1.1     pooka 		{
    364       1.1     pooka 			INIT(vnmsg_lookup);
    365       1.1     pooka 
    366       1.1     pooka 			ASSIGN(pvn_pr);
    367       1.1     pooka 			ASSIGN(pvnr_newnode);
    368       1.1     pooka 			ASSIGN(pvnr_vtype);
    369       1.1     pooka 			ASSIGN(pvnr_size);
    370       1.1     pooka 			ASSIGN(pvnr_rdev);
    371       1.1     pooka 
    372       1.1     pooka 			break;
    373       1.1     pooka 		}
    374       1.1     pooka 
    375       1.1     pooka 		case PUFFS_VN_CREATE:
    376       1.1     pooka 		{
    377       1.1     pooka 			INIT(vnmsg_create);
    378       1.1     pooka 
    379       1.1     pooka 			ASSIGN(pvn_pr);
    380       1.1     pooka 			ASSIGN(pvnr_newnode);
    381       1.1     pooka 
    382       1.1     pooka 			break;
    383       1.1     pooka 		}
    384       1.1     pooka 
    385       1.1     pooka 		case PUFFS_VN_MKNOD:
    386       1.1     pooka 		{
    387       1.1     pooka 			INIT(vnmsg_mknod);
    388       1.1     pooka 
    389       1.1     pooka 			ASSIGN(pvn_pr);
    390       1.1     pooka 			ASSIGN(pvnr_newnode);
    391       1.1     pooka 
    392       1.1     pooka 			break;
    393       1.1     pooka 		}
    394       1.1     pooka 
    395       1.1     pooka 		case PUFFS_VN_MKDIR:
    396       1.1     pooka 		{
    397       1.1     pooka 			INIT(vnmsg_mkdir);
    398       1.1     pooka 
    399       1.1     pooka 			ASSIGN(pvn_pr);
    400       1.1     pooka 			ASSIGN(pvnr_newnode);
    401       1.1     pooka 
    402       1.1     pooka 			break;
    403       1.1     pooka 		}
    404       1.1     pooka 
    405       1.1     pooka 		case PUFFS_VN_SYMLINK:
    406       1.1     pooka 		{
    407       1.1     pooka 			INIT(vnmsg_symlink);
    408       1.1     pooka 
    409       1.1     pooka 			ASSIGN(pvn_pr);
    410       1.1     pooka 			ASSIGN(pvnr_newnode);
    411       1.1     pooka 
    412       1.1     pooka 			break;
    413       1.1     pooka 		}
    414       1.1     pooka 
    415       1.1     pooka 		case PUFFS_VN_SETATTR:
    416       1.1     pooka 		{
    417       1.1     pooka 			INIT(vnmsg_setattr);
    418       1.1     pooka 
    419       1.1     pooka 			ASSIGN(pvn_pr);
    420       1.1     pooka 
    421       1.1     pooka 			break;
    422       1.1     pooka 		}
    423       1.1     pooka 		case PUFFS_VN_GETATTR:
    424       1.1     pooka 		{
    425       1.1     pooka 			INIT(vnmsg_getattr);
    426       1.1     pooka 
    427       1.1     pooka 			ASSIGN(pvn_pr);
    428       1.1     pooka 			vattr_from_50(&cmsg->pvnr_va, &omsg->pvnr_va);
    429       1.1     pooka 
    430       1.1     pooka 			break;
    431       1.1     pooka 		}
    432       1.1     pooka 
    433       1.1     pooka 		default:
    434       1.1     pooka 			panic("puffs compat ops come in pairs");
    435       1.1     pooka 		}
    436       1.1     pooka 	}
    437  1.4.16.2  pgoyette 	return 0;
    438  1.4.16.1  pgoyette }
    439  1.4.16.1  pgoyette 
    440  1.4.16.2  pgoyette COMPAT_SET_HOOK2(puffs50_compat_hook, "pffs50", puffs_compat_outgoing,
    441  1.4.16.2  pgoyette     puffs_compat_incoming);
    442  1.4.16.2  pgoyette COMPAT_UNSET_HOOK2(puffs50_compat_hook);
    443  1.4.16.2  pgoyette 
    444  1.4.16.1  pgoyette void puffs_50_init(void)
    445  1.4.16.1  pgoyette {
    446  1.4.16.1  pgoyette 
    447  1.4.16.2  pgoyette 	puffs50_compat_hook_set();
    448  1.4.16.1  pgoyette }
    449  1.4.16.1  pgoyette 
    450  1.4.16.1  pgoyette void puffs_50_fini(void)
    451  1.4.16.1  pgoyette {
    452  1.4.16.1  pgoyette 
    453  1.4.16.2  pgoyette 	puffs50_compat_hook_unset();
    454       1.1     pooka }
    455