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.
*/