Module Name:    src
Committed By:   pooka
Date:           Fri May 21 10:16:54 UTC 2010

Modified Files:
        src/sys/fs/puffs: puffs_msgif.h puffs_vfsops.c puffs_vnops.c

Log Message:
Support extended attributes.


To generate a diff of this commit:
cvs rdiff -u -r1.70 -r1.71 src/sys/fs/puffs/puffs_msgif.h
cvs rdiff -u -r1.87 -r1.88 src/sys/fs/puffs/puffs_vfsops.c
cvs rdiff -u -r1.144 -r1.145 src/sys/fs/puffs/puffs_vnops.c

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/sys/fs/puffs/puffs_msgif.h
diff -u src/sys/fs/puffs/puffs_msgif.h:1.70 src/sys/fs/puffs/puffs_msgif.h:1.71
--- src/sys/fs/puffs/puffs_msgif.h:1.70	Thu May 20 12:09:45 2010
+++ src/sys/fs/puffs/puffs_msgif.h	Fri May 21 10:16:54 2010
@@ -1,4 +1,4 @@
-/*	$NetBSD: puffs_msgif.h,v 1.70 2010/05/20 12:09:45 pooka Exp $	*/
+/*	$NetBSD: puffs_msgif.h,v 1.71 2010/05/21 10:16:54 pooka Exp $	*/
 
 /*
  * Copyright (c) 2005, 2006, 2007  Antti Kantee.  All Rights Reserved.
@@ -69,7 +69,8 @@
 	PUFFS_VFS_INIT,		PUFFS_VFS_DONE,		PUFFS_VFS_SNAPSHOT,
 	PUFFS_VFS_EXTATTRCTL,	PUFFS_VFS_SUSPEND
 };
-#define PUFFS_VFS_MAX PUFFS_VFS_EXTATTRCTL /* XXX: NOT TRUE!! */
+#define PUFFS_VFS_SPARE 0
+#define PUFFS_VFS_MAX (PUFFS_VFS_EXTATTRCTL+PUFFS_VFS_SPARE)
 
 /* moreXXX: we don't need everything here either */
 enum {
@@ -88,9 +89,10 @@
 	PUFFS_VN_ADVLOCK,	PUFFS_VN_LEASE,		PUFFS_VN_WHITEOUT,
 	PUFFS_VN_GETPAGES,	PUFFS_VN_PUTPAGES,	PUFFS_VN_GETEXTATTR,
 	PUFFS_VN_LISTEXTATTR,	PUFFS_VN_OPENEXTATTR,	PUFFS_VN_DELETEEXTATTR,
-	PUFFS_VN_SETEXTATTR
+	PUFFS_VN_SETEXTATTR	/* PUFFS_VN_CLOSEEXTATTR */
 };
-#define PUFFS_VN_MAX PUFFS_VN_SETEXTATTR
+#define PUFFS_VN_SPARE 0
+#define PUFFS_VN_MAX (PUFFS_VN_SETEXTATTR+PUFFS_VN_SPARE)
 
 /*
  * These signal invalid parameters the file system returned.
@@ -102,6 +104,10 @@
 };
 #define PUFFS_ERR_MAX PUFFS_ERR_VPTOFH
 
+/* trick to avoid protocol bump */
+#define PUFFS_ERR_GETEXTATTR PUFFS_ERR_ERROR
+#define PUFFS_ERR_LISTEXTATTR PUFFS_ERR_ERROR
+
 #define PUFFSDEVELVERS	0x80000000
 #define PUFFSVERSION	29
 #define PUFFSNAMESIZE	32
@@ -247,6 +253,8 @@
 #define PUFFS_MSG_MAXSIZE	2*MAXPHYS
 #define PUFFS_MSGSTRUCT_MAX	4096 /* XXX: approxkludge */
 
+#define PUFFS_EXTNAMELEN NAME_MAX /* currently same as EXTATTR_MAXNAMELEN */
+
 #define PUFFS_TOMOVE(a,b) (MIN((a), b->pmp_msg_maxsize - PUFFS_MSGSTRUCT_MAX))
 
 /* puffs struct componentname built by kernel */
@@ -327,6 +335,17 @@
 #define PUFFS_SUSPEND_RESUME	2
 #define PUFFS_SUSPEND_ERROR	3
 
+#define PUFFS_EXTATTRCTL_HASNODE	0x01
+#define PUFFS_EXTATTRCTL_HASATTRNAME	0x02
+struct puffs_vfsmsg_extattrctl {
+	struct puffs_req	pvfsr_pr;
+
+	int			pvfsr_cmd;			  /* OUT */
+	int			pvfsr_attrnamespace;		  /* OUT */
+	int			pvfsr_flags;			  /* OUT */
+	char			pvfsr_attrname[PUFFS_EXTNAMELEN]; /* OUT */
+};
+
 /*
  * aux structures for vnode operations.
  */
@@ -571,6 +590,54 @@
 	struct puffs_kcred	pvnr_cn_cred;		/* OUT	*/
 };
 
+struct puffs_vnmsg_getextattr {
+	struct puffs_req	pvn_pr;
+
+	int			pvnr_attrnamespace;		/* OUT	  */
+	char			pvnr_attrname[PUFFS_EXTNAMELEN];/* OUT	  */
+
+	struct puffs_kcred	pvnr_cred;			/* OUT	  */
+	size_t			pvnr_datasize;			/* IN	  */
+
+	size_t			pvnr_resid;			/* IN/OUT */
+	uint8_t			pvnr_data[0]			/* IN	  */
+				    __aligned(ALIGNBYTES+1);
+};
+
+struct puffs_vnmsg_setextattr {
+	struct puffs_req	pvn_pr;
+
+	int			pvnr_attrnamespace;		/* OUT	  */
+	char			pvnr_attrname[PUFFS_EXTNAMELEN];/* OUT	  */
+
+	struct puffs_kcred	pvnr_cred;			/* OUT	*/
+
+	size_t			pvnr_resid;			/* IN/OUT */
+	uint8_t			pvnr_data[0]			/* OUT	  */
+				    __aligned(ALIGNBYTES+1);
+};
+
+struct puffs_vnmsg_listextattr {
+	struct puffs_req	pvn_pr;
+
+	int			pvnr_attrnamespace;		/* OUT	  */
+
+	struct puffs_kcred	pvnr_cred;			/* OUT	*/
+	size_t			pvnr_datasize;			/* IN	  */
+
+	size_t			pvnr_resid;			/* IN/OUT */
+	uint8_t			pvnr_data[0]			/* IN	  */
+				    __aligned(ALIGNBYTES+1);
+};
+
+struct puffs_vnmsg_deleteextattr {
+	struct puffs_req	pvn_pr;
+
+	int			pvnr_attrnamespace;		/* OUT	  */
+	char			pvnr_attrname[PUFFS_EXTNAMELEN];/* OUT	  */
+
+	struct puffs_kcred	pvnr_cred;			/* OUT	*/
+};
 
 /*
  * For cache reports.  Everything is always out-out-out, no replies

Index: src/sys/fs/puffs/puffs_vfsops.c
diff -u src/sys/fs/puffs/puffs_vfsops.c:1.87 src/sys/fs/puffs/puffs_vfsops.c:1.88
--- src/sys/fs/puffs/puffs_vfsops.c:1.87	Wed Feb 17 14:32:08 2010
+++ src/sys/fs/puffs/puffs_vfsops.c	Fri May 21 10:16:54 2010
@@ -1,4 +1,4 @@
-/*	$NetBSD: puffs_vfsops.c,v 1.87 2010/02/17 14:32:08 pooka Exp $	*/
+/*	$NetBSD: puffs_vfsops.c,v 1.88 2010/05/21 10:16:54 pooka Exp $	*/
 
 /*
  * Copyright (c) 2005, 2006  Antti Kantee.  All Rights Reserved.
@@ -30,7 +30,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: puffs_vfsops.c,v 1.87 2010/02/17 14:32:08 pooka Exp $");
+__KERNEL_RCSID(0, "$NetBSD: puffs_vfsops.c,v 1.88 2010/05/21 10:16:54 pooka Exp $");
 
 #include <sys/param.h>
 #include <sys/mount.h>
@@ -758,6 +758,56 @@
 	return EOPNOTSUPP;
 }
 
+int
+puffs_vfsop_extattrctl(struct mount *mp, int cmd, struct vnode *vp,
+	int attrnamespace, const char *attrname)
+{
+	PUFFS_MSG_VARS(vfs, extattrctl);
+	struct puffs_mount *pmp = MPTOPUFFSMP(mp);
+	struct puffs_node *pnp;
+	puffs_cookie_t pnc;
+	int error, flags;
+
+	if (vp) {
+		/* doesn't make sense for puffs servers */
+		if (vp->v_mount != mp)
+			return EXDEV;
+		pnp = vp->v_data;
+		pnc = pnp->pn_cookie;
+		flags = PUFFS_EXTATTRCTL_HASNODE;
+	} else {
+		pnp = pnc = NULL;
+		flags = 0;
+	}
+
+	PUFFS_MSG_ALLOC(vfs, extattrctl);
+	extattrctl_msg->pvfsr_cmd = cmd;
+	extattrctl_msg->pvfsr_attrnamespace = attrnamespace;
+	extattrctl_msg->pvfsr_flags = flags;
+	if (attrname) {
+		strlcpy(extattrctl_msg->pvfsr_attrname, attrname,
+		    sizeof(extattrctl_msg->pvfsr_attrname));
+		extattrctl_msg->pvfsr_flags |= PUFFS_EXTATTRCTL_HASATTRNAME;
+	}
+	puffs_msg_setinfo(park_extattrctl,
+	    PUFFSOP_VFS, PUFFS_VFS_EXTATTRCTL, pnc);
+
+	puffs_msg_enqueue(pmp, park_extattrctl);
+	if (vp) {
+		mutex_enter(&pnp->pn_mtx);
+		puffs_referencenode(pnp);
+		mutex_exit(&pnp->pn_mtx);
+		VOP_UNLOCK(vp, 0);
+	}
+	error = puffs_msg_wait2(pmp, park_extattrctl, pnp, NULL);
+	PUFFS_MSG_RELEASE(extattrctl);
+	if (vp) {
+		puffs_releasenode(pnp);
+	}
+
+	return checkerr(pmp, error, __func__);
+}
+
 const struct vnodeopv_desc * const puffs_vnodeopv_descs[] = {
 	&puffs_vnodeop_opv_desc,
 	&puffs_specop_opv_desc,
@@ -784,7 +834,7 @@
 	puffs_vfsop_done,		/* done		*/
 	NULL,				/* mountroot	*/
 	puffs_vfsop_snapshot,		/* snapshot	*/
-	vfs_stdextattrctl,		/* extattrctl	*/
+	puffs_vfsop_extattrctl,		/* extattrctl	*/
 	(void *)eopnotsupp,		/* suspendctl	*/
 	genfs_renamelock_enter,
 	genfs_renamelock_exit,

Index: src/sys/fs/puffs/puffs_vnops.c
diff -u src/sys/fs/puffs/puffs_vnops.c:1.144 src/sys/fs/puffs/puffs_vnops.c:1.145
--- src/sys/fs/puffs/puffs_vnops.c:1.144	Mon Mar 29 13:11:33 2010
+++ src/sys/fs/puffs/puffs_vnops.c	Fri May 21 10:16:54 2010
@@ -1,4 +1,4 @@
-/*	$NetBSD: puffs_vnops.c,v 1.144 2010/03/29 13:11:33 pooka Exp $	*/
+/*	$NetBSD: puffs_vnops.c,v 1.145 2010/05/21 10:16:54 pooka Exp $	*/
 
 /*
  * Copyright (c) 2005, 2006, 2007  Antti Kantee.  All Rights Reserved.
@@ -30,7 +30,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: puffs_vnops.c,v 1.144 2010/03/29 13:11:33 pooka Exp $");
+__KERNEL_RCSID(0, "$NetBSD: puffs_vnops.c,v 1.145 2010/05/21 10:16:54 pooka Exp $");
 
 #include <sys/param.h>
 #include <sys/buf.h>
@@ -82,6 +82,10 @@
 int	puffs_vnop_mmap(void *);
 int	puffs_vnop_getpages(void *);
 int	puffs_vnop_abortop(void *);
+int	puffs_vnop_getextattr(void *);
+int	puffs_vnop_setextattr(void *);
+int	puffs_vnop_listextattr(void *);
+int	puffs_vnop_deleteextattr(void *);
 
 int	puffs_vnop_spec_read(void *);
 int	puffs_vnop_spec_write(void *);
@@ -134,7 +138,14 @@
         { &vop_bwrite_desc, genfs_nullop },		/* REAL bwrite */
         { &vop_mmap_desc, puffs_vnop_mmap },		/* REAL mmap */
         { &vop_poll_desc, puffs_vnop_poll },		/* REAL poll */
-
+	{ &vop_getextattr_desc, puffs_vnop_getextattr },	/* getextattr */
+	{ &vop_setextattr_desc, puffs_vnop_setextattr },	/* setextattr */
+	{ &vop_listextattr_desc, puffs_vnop_listextattr },	/* listextattr */
+	{ &vop_deleteextattr_desc, puffs_vnop_deleteextattr },/* deleteextattr */
+#if 0
+	{ &vop_openextattr_desc, puffs_vnop_checkop },	/* openextattr */
+	{ &vop_closeextattr_desc, puffs_vnop_checkop },	/* closeextattr */
+#endif
         { &vop_kqfilter_desc, genfs_eopnotsupp },	/* kqfilter XXX */
 	{ NULL, NULL }
 };
@@ -185,13 +196,13 @@
 	{ &vop_bwrite_desc, vn_bwrite },		/* bwrite */
 	{ &vop_getpages_desc, spec_getpages },		/* genfs_getpages */
 	{ &vop_putpages_desc, spec_putpages },		/* genfs_putpages */
+	{ &vop_getextattr_desc, puffs_vnop_checkop },	/* getextattr */
+	{ &vop_setextattr_desc, puffs_vnop_checkop },	/* setextattr */
+	{ &vop_listextattr_desc, puffs_vnop_checkop },	/* listextattr */
+	{ &vop_deleteextattr_desc, puffs_vnop_checkop },/* deleteextattr */
 #if 0
 	{ &vop_openextattr_desc, _openextattr },	/* openextattr */
 	{ &vop_closeextattr_desc, _closeextattr },	/* closeextattr */
-	{ &vop_getextattr_desc, _getextattr },		/* getextattr */
-	{ &vop_setextattr_desc, _setextattr },		/* setextattr */
-	{ &vop_listextattr_desc, _listextattr },	/* listextattr */
-	{ &vop_deleteextattr_desc, _deleteextattr },	/* deleteextattr */
 #endif
 	{ NULL, NULL }
 };
@@ -244,11 +255,11 @@
 #if 0
 	{ &vop_openextattr_desc, _openextattr },	/* openextattr */
 	{ &vop_closeextattr_desc, _closeextattr },	/* closeextattr */
-	{ &vop_getextattr_desc, _getextattr },		/* getextattr */
-	{ &vop_setextattr_desc, _setextattr },		/* setextattr */
-	{ &vop_listextattr_desc, _listextattr },	/* listextattr */
-	{ &vop_deleteextattr_desc, _deleteextattr },	/* deleteextattr */
 #endif
+	{ &vop_getextattr_desc, puffs_vnop_checkop },		/* getextattr */
+	{ &vop_setextattr_desc, puffs_vnop_checkop },		/* setextattr */
+	{ &vop_listextattr_desc, puffs_vnop_checkop },	/* listextattr */
+	{ &vop_deleteextattr_desc, puffs_vnop_checkop },	/* deleteextattr */
 	{ NULL, NULL }
 };
 const struct vnodeopv_desc puffs_fifoop_opv_desc =
@@ -365,6 +376,10 @@
 			CHECKOP_NOTSUPP(PRINT);
 			CHECKOP_NOTSUPP(PATHCONF);
 			CHECKOP_NOTSUPP(ADVLOCK);
+			CHECKOP_NOTSUPP(GETEXTATTR);
+			CHECKOP_NOTSUPP(SETEXTATTR);
+			CHECKOP_NOTSUPP(LISTEXTATTR);
+			CHECKOP_NOTSUPP(DELETEEXTATTR);
 
 			CHECKOP_SUCCESS(ACCESS);
 			CHECKOP_SUCCESS(CLOSE);
@@ -2582,6 +2597,241 @@
 }
 
 /*
+ * Extended attribute support.
+ */
+
+int
+puffs_vnop_getextattr(void *v)
+{
+	struct vop_getextattr_args /* 
+		struct vnode *a_vp;
+		int a_attrnamespace;
+		const char *a_name;
+		struct uio *a_uio;
+		size_t *a_size;
+		kauth_cred_t a_cred;
+	}; */ *ap = v;
+	PUFFS_MSG_VARS(vn, getextattr);
+	struct vnode *vp = ap->a_vp;
+	struct puffs_mount *pmp = MPTOPUFFSMP(vp->v_mount);
+	int attrnamespace = ap->a_attrnamespace;
+	const char *name = ap->a_name;
+	struct uio *uio = ap->a_uio;
+	size_t *sizep = ap->a_size;
+	size_t tomove, resid;
+	int error;
+
+	if (uio)
+		resid = uio->uio_resid;
+	else
+		resid = 0;
+
+	tomove = PUFFS_TOMOVE(resid, pmp);
+	if (tomove != resid) {
+		error = E2BIG;
+		goto out;
+	}
+
+	puffs_msgmem_alloc(sizeof(struct puffs_vnmsg_getextattr) + tomove,
+	    &park_getextattr, (void *)&getextattr_msg, 1);
+
+	getextattr_msg->pvnr_attrnamespace = attrnamespace;
+	strlcpy(getextattr_msg->pvnr_attrname, name,
+	    sizeof(getextattr_msg->pvnr_attrname));
+	puffs_credcvt(&getextattr_msg->pvnr_cred, ap->a_cred);
+	if (sizep)
+		getextattr_msg->pvnr_datasize = 1;
+	getextattr_msg->pvnr_resid = tomove;
+
+	puffs_msg_setinfo(park_getextattr,
+	    PUFFSOP_VN, PUFFS_VN_GETEXTATTR, VPTOPNC(vp));
+	puffs_msg_setdelta(park_getextattr, tomove);
+	PUFFS_MSG_ENQUEUEWAIT2(pmp, park_getextattr, vp->v_data, NULL, error);
+
+	error = checkerr(pmp, error, __func__);
+	if (error)
+		goto out;
+
+	resid = getextattr_msg->pvnr_resid;
+	if (resid > tomove) {
+		puffs_senderr(pmp, PUFFS_ERR_GETEXTATTR, E2BIG,
+		    "resid grew", VPTOPNC(vp));
+		error = EPROTO;
+		goto out;
+	}
+
+	if (sizep)
+		*sizep = getextattr_msg->pvnr_datasize;
+	if (uio)
+		error = uiomove(getextattr_msg->pvnr_data, tomove - resid, uio);
+
+ out:
+	PUFFS_MSG_RELEASE(getextattr);
+	return error;
+}
+
+int
+puffs_vnop_setextattr(void *v)
+{
+	struct vop_setextattr_args /* {
+		struct vnode *a_vp;
+		int a_attrnamespace;
+		const char *a_name;
+		struct uio *a_uio;
+		kauth_cred_t a_cred;
+	}; */ *ap = v;
+	PUFFS_MSG_VARS(vn, setextattr);
+	struct vnode *vp = ap->a_vp;
+	struct puffs_mount *pmp = MPTOPUFFSMP(vp->v_mount);
+	int attrnamespace = ap->a_attrnamespace;
+	const char *name = ap->a_name;
+	struct uio *uio = ap->a_uio;
+	size_t tomove, resid;
+	int error;
+
+	if (uio)
+		resid = uio->uio_resid;
+	else
+		resid = 0;
+
+	tomove = PUFFS_TOMOVE(resid, pmp);
+	if (tomove != resid) {
+		error = E2BIG;
+		goto out;
+	}
+
+	puffs_msgmem_alloc(sizeof(struct puffs_vnmsg_setextattr) + tomove,
+	    &park_setextattr, (void *)&setextattr_msg, 1);
+
+	setextattr_msg->pvnr_attrnamespace = attrnamespace;
+	strlcpy(setextattr_msg->pvnr_attrname, name,
+	    sizeof(setextattr_msg->pvnr_attrname));
+	puffs_credcvt(&setextattr_msg->pvnr_cred, ap->a_cred);
+	setextattr_msg->pvnr_resid = tomove;
+
+	if (uio) {
+		error = uiomove(setextattr_msg->pvnr_data, tomove, uio);
+		if (error)
+			goto out;
+	}
+
+	puffs_msg_setinfo(park_setextattr,
+	    PUFFSOP_VN, PUFFS_VN_SETEXTATTR, VPTOPNC(vp));
+	PUFFS_MSG_ENQUEUEWAIT2(pmp, park_setextattr, vp->v_data, NULL, error);
+
+	error = checkerr(pmp, error, __func__);
+	if (error)
+		goto out;
+
+	if (setextattr_msg->pvnr_resid != 0)
+		error = EIO;
+
+ out:
+	PUFFS_MSG_RELEASE(setextattr);
+
+	return error;
+}
+
+int
+puffs_vnop_listextattr(void *v)
+{
+	struct vop_listextattr_args /* {
+		struct vnode *a_vp;
+		int a_attrnamespace;
+		struct uio *a_uio;
+		size_t *a_size;
+		kauth_cred_t a_cred;
+	}; */ *ap = v;
+	PUFFS_MSG_VARS(vn, listextattr);
+	struct vnode *vp = ap->a_vp;
+	struct puffs_mount *pmp = MPTOPUFFSMP(vp->v_mount);
+	int attrnamespace = ap->a_attrnamespace;
+	struct uio *uio = ap->a_uio;
+	size_t *sizep = ap->a_size;
+	size_t tomove, resid;
+	int error;
+
+	if (uio)
+		resid = uio->uio_resid;
+	else
+		resid = 0;
+
+	tomove = PUFFS_TOMOVE(resid, pmp);
+	if (tomove != resid) {
+		error = E2BIG;
+		goto out;
+	}
+
+	puffs_msgmem_alloc(sizeof(struct puffs_vnmsg_listextattr) + tomove,
+	    &park_listextattr, (void *)&listextattr_msg, 1);
+
+	listextattr_msg->pvnr_attrnamespace = attrnamespace;
+	puffs_credcvt(&listextattr_msg->pvnr_cred, ap->a_cred);
+	listextattr_msg->pvnr_resid = tomove;
+	if (sizep)
+		listextattr_msg->pvnr_datasize = 1;
+
+	puffs_msg_setinfo(park_listextattr,
+	    PUFFSOP_VN, PUFFS_VN_LISTEXTATTR, VPTOPNC(vp));
+	puffs_msg_setdelta(park_listextattr, tomove);
+	PUFFS_MSG_ENQUEUEWAIT2(pmp, park_listextattr, vp->v_data, NULL, error);
+
+	error = checkerr(pmp, error, __func__);
+	if (error)
+		goto out;
+
+	resid = listextattr_msg->pvnr_resid;
+	if (resid > tomove) {
+		puffs_senderr(pmp, PUFFS_ERR_LISTEXTATTR, E2BIG,
+		    "resid grew", VPTOPNC(vp));
+		error = EPROTO;
+		goto out;
+	}
+
+	if (sizep)
+		*sizep = listextattr_msg->pvnr_datasize;
+	if (uio)
+		error = uiomove(listextattr_msg->pvnr_data, tomove-resid, uio);
+
+ out:
+	PUFFS_MSG_RELEASE(listextattr);
+	return error;
+}
+
+int
+puffs_vnop_deleteextattr(void *v)
+{
+	struct vop_deleteextattr_args /* {
+		struct vnode *a_vp;
+		int a_attrnamespace;
+		const char *a_name;
+		kauth_cred_t a_cred;
+	}; */ *ap = v;
+	PUFFS_MSG_VARS(vn, deleteextattr);
+	struct vnode *vp = ap->a_vp;
+	struct puffs_mount *pmp = MPTOPUFFSMP(vp->v_mount);
+	int attrnamespace = ap->a_attrnamespace;
+	const char *name = ap->a_name;
+	int error;
+
+	PUFFS_MSG_ALLOC(vn, deleteextattr);
+	deleteextattr_msg->pvnr_attrnamespace = attrnamespace;
+	strlcpy(deleteextattr_msg->pvnr_attrname, name,
+	    sizeof(deleteextattr_msg->pvnr_attrname));
+	puffs_credcvt(&deleteextattr_msg->pvnr_cred, ap->a_cred);
+
+	puffs_msg_setinfo(park_deleteextattr,
+	    PUFFSOP_VN, PUFFS_VN_DELETEEXTATTR, VPTOPNC(vp));
+	PUFFS_MSG_ENQUEUEWAIT2(pmp, park_deleteextattr,
+	    vp->v_data, NULL, error);
+
+	error = checkerr(pmp, error, __func__);
+
+	PUFFS_MSG_RELEASE(deleteextattr);
+	return error;
+}
+
+/*
  * spec & fifo.  These call the miscfs spec and fifo vectors, but issue
  * FAF update information for the puffs node first.
  */

Reply via email to