Module Name: src Committed By: manu Date: Mon Jul 4 08:07:32 UTC 2011
Modified Files: src/lib/libp2k: p2k.c src/lib/libperfuse: ops.c perfuse_priv.h src/lib/libpuffs: dispatcher.c puffs.h puffs_ops.3 src/sys/fs/puffs: puffs_msgif.h puffs_vnops.c src/sys/kern: vfs_xattr.c vnode_if.c src/sys/rump/include/rump: rumpvnode_if.h src/sys/rump/librump/rumpvfs: rumpvnode_if.c src/sys/sys: extattr.h vnode_if.h src/sys/ufs/ufs: ufs_extattr.c src/usr.bin/extattr: getextattr.c Log Message: Add a flag to VOP_LISTEXTATTR(9) so that the vnode interface can tell the filesystem in which format extended attribute shall be listed. There are currently two formats: - NUL-terminated strings, used for listxattr(2), this is the default. - one byte length-pprefixed, non NUL-terminated strings, used for extattr_list_file(2), which is obtanined by setting the EXTATTR_LIST_PREFIXLEN flag to VOP_LISTEXTATTR(9) This approach avoid the need for converting the list back and forth, except in libperfuse, since FUSE uses NUL-terminated strings, and the kernel may have requested EXTATTR_LIST_PREFIXLEN. To generate a diff of this commit: cvs rdiff -u -r1.54 -r1.55 src/lib/libp2k/p2k.c cvs rdiff -u -r1.31 -r1.32 src/lib/libperfuse/ops.c cvs rdiff -u -r1.19 -r1.20 src/lib/libperfuse/perfuse_priv.h cvs rdiff -u -r1.35 -r1.36 src/lib/libpuffs/dispatcher.c cvs rdiff -u -r1.117 -r1.118 src/lib/libpuffs/puffs.h cvs rdiff -u -r1.28 -r1.29 src/lib/libpuffs/puffs_ops.3 cvs rdiff -u -r1.75 -r1.76 src/sys/fs/puffs/puffs_msgif.h cvs rdiff -u -r1.153 -r1.154 src/sys/fs/puffs/puffs_vnops.c cvs rdiff -u -r1.26 -r1.27 src/sys/kern/vfs_xattr.c cvs rdiff -u -r1.86 -r1.87 src/sys/kern/vnode_if.c cvs rdiff -u -r1.9 -r1.10 src/sys/rump/include/rump/rumpvnode_if.h cvs rdiff -u -r1.8 -r1.9 src/sys/rump/librump/rumpvfs/rumpvnode_if.c cvs rdiff -u -r1.5 -r1.6 src/sys/sys/extattr.h cvs rdiff -u -r1.80 -r1.81 src/sys/sys/vnode_if.h cvs rdiff -u -r1.33 -r1.34 src/sys/ufs/ufs/ufs_extattr.c cvs rdiff -u -r1.6 -r1.7 src/usr.bin/extattr/getextattr.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
Modified files: Index: src/lib/libp2k/p2k.c diff -u src/lib/libp2k/p2k.c:1.54 src/lib/libp2k/p2k.c:1.55 --- src/lib/libp2k/p2k.c:1.54 Fri Jan 7 16:02:32 2011 +++ src/lib/libp2k/p2k.c Mon Jul 4 08:07:29 2011 @@ -1,4 +1,4 @@ -/* $NetBSD: p2k.c,v 1.54 2011/01/07 16:02:32 pooka Exp $ */ +/* $NetBSD: p2k.c,v 1.55 2011/07/04 08:07:29 manu Exp $ */ /* * Copyright (c) 2007, 2008, 2009 Antti Kantee. All Rights Reserved. @@ -1304,8 +1304,8 @@ /*ARGSUSED*/ int p2k_node_listextattr(struct puffs_usermount *pu, puffs_cookie_t opc, - int attrnamespace, size_t *attrsize, - uint8_t *attrs, size_t *resid, const struct puffs_cred *pcr) + int attrnamespace, size_t *attrsize, uint8_t *attrs, + size_t *resid, int flags, const struct puffs_cred *pcr) { struct vnode *vp = OPC2VP(opc); struct kauth_cred *cred; @@ -1319,7 +1319,8 @@ cred = cred_create(pcr); RUMP_VOP_LOCK(vp, LK_EXCLUSIVE); - rv = RUMP_VOP_LISTEXTATTR(vp, attrnamespace, uio, attrsize, cred); + rv = RUMP_VOP_LISTEXTATTR(vp, attrnamespace, uio, attrsize, + flags, cred); RUMP_VOP_UNLOCK(vp); cred_destroy(cred); Index: src/lib/libperfuse/ops.c diff -u src/lib/libperfuse/ops.c:1.31 src/lib/libperfuse/ops.c:1.32 --- src/lib/libperfuse/ops.c:1.31 Tue Jun 28 16:19:16 2011 +++ src/lib/libperfuse/ops.c Mon Jul 4 08:07:29 2011 @@ -1,4 +1,4 @@ -/* $NetBSD: ops.c,v 1.31 2011/06/28 16:19:16 manu Exp $ */ +/* $NetBSD: ops.c,v 1.32 2011/07/04 08:07:29 manu Exp $ */ /*- * Copyright (c) 2010-2011 Emmanuel Dreyfus. All rights reserved. @@ -3040,13 +3040,14 @@ /* ARGSUSED2 */ int -perfuse_node_listextattr(pu, opc, attrns, attrsize, attrs, resid, pcr) +perfuse_node_listextattr(pu, opc, attrns, attrsize, attrs, resid, flag, pcr) struct puffs_usermount *pu; puffs_cookie_t opc; int attrns; size_t *attrsize; uint8_t *attrs; size_t *resid; + int flag; const struct puffs_cred *pcr; { struct perfuse_state *ps; @@ -3093,6 +3094,19 @@ puffs_len = foh->len - sizeof(*foh); if (attrs != NULL) { + /* + * Convert the FUSE reply to length prefixed strings + * if this is what the kernel wants. + */ + if (flag & PUFFS_EXTATTR_LIST_LENPREFIX) { + size_t i, attrlen; + + for (i = 0; i < puffs_len; i += attrlen + 1) { + attrlen = strlen(np + i); + (void)memmove(np + i + 1, np + i, attrlen); + *(np + i) = (uint8_t)attrlen; + } + } (void)memcpy(attrs, np, puffs_len); *resid -= puffs_len; } Index: src/lib/libperfuse/perfuse_priv.h diff -u src/lib/libperfuse/perfuse_priv.h:1.19 src/lib/libperfuse/perfuse_priv.h:1.20 --- src/lib/libperfuse/perfuse_priv.h:1.19 Tue Jun 28 16:19:16 2011 +++ src/lib/libperfuse/perfuse_priv.h Mon Jul 4 08:07:30 2011 @@ -1,4 +1,4 @@ -/* $NetBSD: perfuse_priv.h,v 1.19 2011/06/28 16:19:16 manu Exp $ */ +/* $NetBSD: perfuse_priv.h,v 1.20 2011/07/04 08:07:30 manu Exp $ */ /*- * Copyright (c) 2010-2011 Emmanuel Dreyfus. All rights reserved. @@ -228,7 +228,7 @@ int perfuse_node_setextattr(struct puffs_usermount *, puffs_cookie_t, int, const char *, uint8_t *, size_t *, const struct puffs_cred *); int perfuse_node_listextattr(struct puffs_usermount *, puffs_cookie_t, - int, size_t *, uint8_t *, size_t *, const struct puffs_cred *); + int, size_t *, uint8_t *, size_t *, int, const struct puffs_cred *); int perfuse_node_deleteextattr(struct puffs_usermount *, puffs_cookie_t, int, const char *, const struct puffs_cred *); Index: src/lib/libpuffs/dispatcher.c diff -u src/lib/libpuffs/dispatcher.c:1.35 src/lib/libpuffs/dispatcher.c:1.36 --- src/lib/libpuffs/dispatcher.c:1.35 Mon Dec 6 14:50:34 2010 +++ src/lib/libpuffs/dispatcher.c Mon Jul 4 08:07:30 2011 @@ -1,4 +1,4 @@ -/* $NetBSD: dispatcher.c,v 1.35 2010/12/06 14:50:34 pooka Exp $ */ +/* $NetBSD: dispatcher.c,v 1.36 2011/07/04 08:07:30 manu Exp $ */ /* * Copyright (c) 2006, 2007, 2008 Antti Kantee. All Rights Reserved. @@ -31,7 +31,7 @@ #include <sys/cdefs.h> #if !defined(lint) -__RCSID("$NetBSD: dispatcher.c,v 1.35 2010/12/06 14:50:34 pooka Exp $"); +__RCSID("$NetBSD: dispatcher.c,v 1.36 2011/07/04 08:07:30 manu Exp $"); #endif /* !lint */ #include <sys/types.h> @@ -975,6 +975,7 @@ struct puffs_vnmsg_listextattr *auxt = auxbuf; PUFFS_MAKECRED(pcr, &auxt->pvnr_cred); size_t res, *resp, *sizep; + int flag; uint8_t *data; if (pops->puffs_node_listextattr == NULL) { @@ -997,9 +998,10 @@ } res = auxt->pvnr_resid; + flag = auxt->pvnr_flag; error = pops->puffs_node_listextattr(pu, opcookie, auxt->pvnr_attrnamespace, - sizep, data, resp, pcr); + sizep, data, resp, flag, pcr); /* need to move a bit more? */ preq->preq_buflen = Index: src/lib/libpuffs/puffs.h diff -u src/lib/libpuffs/puffs.h:1.117 src/lib/libpuffs/puffs.h:1.118 --- src/lib/libpuffs/puffs.h:1.117 Mon Jun 7 11:21:31 2010 +++ src/lib/libpuffs/puffs.h Mon Jul 4 08:07:30 2011 @@ -1,4 +1,4 @@ -/* $NetBSD: puffs.h,v 1.117 2010/06/07 11:21:31 pooka Exp $ */ +/* $NetBSD: puffs.h,v 1.118 2011/07/04 08:07:30 manu Exp $ */ /* * Copyright (c) 2005, 2006, 2007 Antti Kantee. All Rights Reserved. @@ -113,6 +113,7 @@ #define PUFFS_FSYNC_DATAONLY 0x0002 #define PUFFS_FSYNC_CACHE 0x0100 +#define PUFFS_EXTATTR_LIST_LENPREFIX 1 /* * Magic constants */ @@ -231,7 +232,7 @@ int (*puffs_node_setextattr)(struct puffs_usermount *, puffs_cookie_t, int, const char *, uint8_t *, size_t *, const struct puffs_cred *); int (*puffs_node_listextattr)(struct puffs_usermount *, puffs_cookie_t, - int, size_t *, uint8_t *, size_t *, const struct puffs_cred *); + int, size_t *, uint8_t *, size_t *, int, const struct puffs_cred *); int (*puffs_node_deleteextattr)(struct puffs_usermount *, puffs_cookie_t, int, const char *, const struct puffs_cred *); @@ -379,7 +380,7 @@ const struct puffs_cred *); \ int fsname##_node_listextattr(struct puffs_usermount *, \ puffs_cookie_t, int, size_t *, uint8_t *, size_t *, \ - const struct puffs_cred *); \ + int, const struct puffs_cred *); \ int fsname##_node_deleteextattr(struct puffs_usermount *, \ puffs_cookie_t, int, const char *, \ const struct puffs_cred *); Index: src/lib/libpuffs/puffs_ops.3 diff -u src/lib/libpuffs/puffs_ops.3:1.28 src/lib/libpuffs/puffs_ops.3:1.29 --- src/lib/libpuffs/puffs_ops.3:1.28 Tue Apr 19 10:35:24 2011 +++ src/lib/libpuffs/puffs_ops.3 Mon Jul 4 08:07:30 2011 @@ -1,4 +1,4 @@ -.\" $NetBSD: puffs_ops.3,v 1.28 2011/04/19 10:35:24 manu Exp $ +.\" $NetBSD: puffs_ops.3,v 1.29 2011/07/04 08:07:30 manu Exp $ .\" .\" Copyright (c) 2007 Antti Kantee. All rights reserved. .\" @@ -196,7 +196,7 @@ .Ft int .Fo puffs_node_listextattr .Fa "struct puffs_usermount *pu" "puffs_cookie_t opc" "int attrnamespace" -.Fa "size_t *attrssize" "uint8_t *attrs" "size_t *resid" +.Fa "size_t *attrssize" "uint8_t *attrs" "iint flag" "size_t *resid" .Fa "const struct puffs_cred *pcr" .Fc .Ft int Index: src/sys/fs/puffs/puffs_msgif.h diff -u src/sys/fs/puffs/puffs_msgif.h:1.75 src/sys/fs/puffs/puffs_msgif.h:1.76 --- src/sys/fs/puffs/puffs_msgif.h:1.75 Tue Jul 6 13:47:47 2010 +++ src/sys/fs/puffs/puffs_msgif.h Mon Jul 4 08:07:30 2011 @@ -1,4 +1,4 @@ -/* $NetBSD: puffs_msgif.h,v 1.75 2010/07/06 13:47:47 pooka Exp $ */ +/* $NetBSD: puffs_msgif.h,v 1.76 2011/07/04 08:07:30 manu Exp $ */ /* * Copyright (c) 2005, 2006, 2007 Antti Kantee. All Rights Reserved. @@ -626,6 +626,7 @@ size_t pvnr_datasize; /* IN */ size_t pvnr_resid; /* IN/OUT */ + int pvnr_flag; /* OUT */ uint8_t pvnr_data[0] /* IN */ __aligned(ALIGNBYTES+1); }; Index: src/sys/fs/puffs/puffs_vnops.c diff -u src/sys/fs/puffs/puffs_vnops.c:1.153 src/sys/fs/puffs/puffs_vnops.c:1.154 --- src/sys/fs/puffs/puffs_vnops.c:1.153 Sun Jun 12 03:35:54 2011 +++ src/sys/fs/puffs/puffs_vnops.c Mon Jul 4 08:07:30 2011 @@ -1,4 +1,4 @@ -/* $NetBSD: puffs_vnops.c,v 1.153 2011/06/12 03:35:54 rmind Exp $ */ +/* $NetBSD: puffs_vnops.c,v 1.154 2011/07/04 08:07:30 manu 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.153 2011/06/12 03:35:54 rmind Exp $"); +__KERNEL_RCSID(0, "$NetBSD: puffs_vnops.c,v 1.154 2011/07/04 08:07:30 manu Exp $"); #include <sys/param.h> #include <sys/buf.h> @@ -2721,6 +2721,7 @@ int a_attrnamespace; struct uio *a_uio; size_t *a_size; + int a_flag, kauth_cred_t a_cred; }; */ *ap = v; PUFFS_MSG_VARS(vn, listextattr); @@ -2729,6 +2730,7 @@ int attrnamespace = ap->a_attrnamespace; struct uio *uio = ap->a_uio; size_t *sizep = ap->a_size; + int flag = ap->a_flag; size_t tomove, resid; int error; @@ -2747,6 +2749,7 @@ &park_listextattr, (void *)&listextattr_msg, 1); listextattr_msg->pvnr_attrnamespace = attrnamespace; + listextattr_msg->pvnr_flag = flag; puffs_credcvt(&listextattr_msg->pvnr_cred, ap->a_cred); listextattr_msg->pvnr_resid = tomove; if (sizep) Index: src/sys/kern/vfs_xattr.c diff -u src/sys/kern/vfs_xattr.c:1.26 src/sys/kern/vfs_xattr.c:1.27 --- src/sys/kern/vfs_xattr.c:1.26 Wed Jun 29 08:01:14 2011 +++ src/sys/kern/vfs_xattr.c Mon Jul 4 08:07:30 2011 @@ -1,4 +1,4 @@ -/* $NetBSD: vfs_xattr.c,v 1.26 2011/06/29 08:01:14 manu Exp $ */ +/* $NetBSD: vfs_xattr.c,v 1.27 2011/07/04 08:07:30 manu Exp $ */ /*- * Copyright (c) 2005, 2008 The NetBSD Foundation, Inc. @@ -68,7 +68,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: vfs_xattr.c,v 1.26 2011/06/29 08:01:14 manu Exp $"); +__KERNEL_RCSID(0, "$NetBSD: vfs_xattr.c,v 1.27 2011/07/04 08:07:30 manu Exp $"); #include <sys/param.h> #include <sys/systm.h> @@ -355,7 +355,7 @@ */ static int extattr_list_vp(struct vnode *vp, int attrnamespace, void *data, size_t nbytes, - struct lwp *l, register_t *retval) + int flag, struct lwp *l, register_t *retval) { struct uio auio, *auiop; size_t size, *sizep; @@ -386,7 +386,8 @@ } else sizep = &size; - error = VOP_LISTEXTATTR(vp, attrnamespace, auiop, sizep, l->l_cred); + error = VOP_LISTEXTATTR(vp, attrnamespace, auiop, sizep, + flag, l->l_cred); if (auiop != NULL) { cnt -= auio.uio_resid; @@ -695,7 +696,8 @@ vp = (struct vnode *) fp->f_data; error = extattr_list_vp(vp, SCARG(uap, attrnamespace), - SCARG(uap, data), SCARG(uap, nbytes), l, retval); + SCARG(uap, data), SCARG(uap, nbytes), + EXTATTR_LIST_LENPREFIX, l, retval); fd_putfile(SCARG(uap, fd)); return (error); @@ -719,7 +721,8 @@ return (error); error = extattr_list_vp(vp, SCARG(uap, attrnamespace), - SCARG(uap, data), SCARG(uap, nbytes), l, retval); + SCARG(uap, data), SCARG(uap, nbytes), + EXTATTR_LIST_LENPREFIX, l, retval); vrele(vp); return (error); @@ -743,7 +746,8 @@ return (error); error = extattr_list_vp(vp, SCARG(uap, attrnamespace), - SCARG(uap, data), SCARG(uap, nbytes), l, retval); + SCARG(uap, data), SCARG(uap, nbytes), + EXTATTR_LIST_LENPREFIX, l, retval); vrele(vp); return (error); @@ -1008,7 +1012,7 @@ size = SCARG(uap, size); error = extattr_list_vp(vp, EXTATTR_NAMESPACE_USER, - list, size, l, &listsize_usr); + list, size, 0, l, &listsize_usr); if (error) goto out; @@ -1018,7 +1022,7 @@ size -= listsize_usr; error = extattr_list_vp(vp, EXTATTR_NAMESPACE_SYSTEM, - list, size, l, &listsize_sys); + list, size, 0, l, &listsize_sys); switch (error) { case EPERM: error = 0; /* Ignore and just skip system EA */ @@ -1061,7 +1065,7 @@ size = SCARG(uap, size); error = extattr_list_vp(vp, EXTATTR_NAMESPACE_USER, - list, size, l, &listsize_usr); + list, size, 0, l, &listsize_usr); if (error) goto out; @@ -1071,7 +1075,7 @@ size -= listsize_usr; error = extattr_list_vp(vp, EXTATTR_NAMESPACE_SYSTEM, - list, size, l, &listsize_sys); + list, size, 0, l, &listsize_sys); switch (error) { case EPERM: error = 0; /* Ignore and just skip system EA */ @@ -1114,7 +1118,7 @@ size = SCARG(uap, size); error = extattr_list_vp(vp, EXTATTR_NAMESPACE_USER, - list, size, l, &listsize_usr); + list, size, 0, l, &listsize_usr); if (error) goto out; @@ -1124,7 +1128,7 @@ size -= listsize_usr; error = extattr_list_vp(vp, EXTATTR_NAMESPACE_SYSTEM, - list, size, l, &listsize_sys); + list, size, 0, l, &listsize_sys); switch (error) { case EPERM: error = 0; /* Ignore and just skip system EA */ Index: src/sys/kern/vnode_if.c diff -u src/sys/kern/vnode_if.c:1.86 src/sys/kern/vnode_if.c:1.87 --- src/sys/kern/vnode_if.c:1.86 Sun Mar 6 17:08:36 2011 +++ src/sys/kern/vnode_if.c Mon Jul 4 08:07:31 2011 @@ -1,4 +1,4 @@ -/* $NetBSD: vnode_if.c,v 1.86 2011/03/06 17:08:36 bouyer Exp $ */ +/* $NetBSD: vnode_if.c,v 1.87 2011/07/04 08:07:31 manu Exp $ */ /* * Warning: DO NOT EDIT! This file is automatically generated! @@ -40,7 +40,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: vnode_if.c,v 1.86 2011/03/06 17:08:36 bouyer Exp $"); +__KERNEL_RCSID(0, "$NetBSD: vnode_if.c,v 1.87 2011/07/04 08:07:31 manu Exp $"); #include <sys/param.h> #include <sys/mount.h> @@ -1519,6 +1519,7 @@ int attrnamespace, struct uio *uio, size_t *size, + int flag, kauth_cred_t cred) { int error; @@ -1529,6 +1530,7 @@ a.a_attrnamespace = attrnamespace; a.a_uio = uio; a.a_size = size; + a.a_flag = flag; a.a_cred = cred; mpsafe = (vp->v_vflag & VV_MPSAFE); if (!mpsafe) { KERNEL_LOCK(1, curlwp); } Index: src/sys/rump/include/rump/rumpvnode_if.h diff -u src/sys/rump/include/rump/rumpvnode_if.h:1.9 src/sys/rump/include/rump/rumpvnode_if.h:1.10 --- src/sys/rump/include/rump/rumpvnode_if.h:1.9 Sun Mar 6 17:08:37 2011 +++ src/sys/rump/include/rump/rumpvnode_if.h Mon Jul 4 08:07:31 2011 @@ -1,4 +1,4 @@ -/* $NetBSD: rumpvnode_if.h,v 1.9 2011/03/06 17:08:37 bouyer Exp $ */ +/* $NetBSD: rumpvnode_if.h,v 1.10 2011/07/04 08:07:31 manu Exp $ */ /* * Warning: DO NOT EDIT! This file is automatically generated! @@ -107,7 +107,7 @@ int RUMP_VOP_GETEXTATTR(struct vnode *, int, const char *, struct uio *, size_t *, struct kauth_cred *); int RUMP_VOP_LISTEXTATTR(struct vnode *, int, struct uio *, size_t *, - struct kauth_cred *); + int, struct kauth_cred *); int RUMP_VOP_OPENEXTATTR(struct vnode *, struct kauth_cred *); int RUMP_VOP_DELETEEXTATTR(struct vnode *, int, const char *, struct kauth_cred *); Index: src/sys/rump/librump/rumpvfs/rumpvnode_if.c diff -u src/sys/rump/librump/rumpvfs/rumpvnode_if.c:1.8 src/sys/rump/librump/rumpvfs/rumpvnode_if.c:1.9 --- src/sys/rump/librump/rumpvfs/rumpvnode_if.c:1.8 Sun Mar 6 17:08:37 2011 +++ src/sys/rump/librump/rumpvfs/rumpvnode_if.c Mon Jul 4 08:07:31 2011 @@ -1,4 +1,4 @@ -/* $NetBSD: rumpvnode_if.c,v 1.8 2011/03/06 17:08:37 bouyer Exp $ */ +/* $NetBSD: rumpvnode_if.c,v 1.9 2011/07/04 08:07:31 manu Exp $ */ /* * Warning: DO NOT EDIT! This file is automatically generated! @@ -40,7 +40,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: rumpvnode_if.c,v 1.8 2011/03/06 17:08:37 bouyer Exp $"); +__KERNEL_RCSID(0, "$NetBSD: rumpvnode_if.c,v 1.9 2011/07/04 08:07:31 manu Exp $"); #include <sys/param.h> #include <sys/mount.h> @@ -677,12 +677,13 @@ int attrnamespace, struct uio *uio, size_t *size, + int flag, struct kauth_cred *cred) { int error; rump_schedule(); - error = VOP_LISTEXTATTR(vp, attrnamespace, uio, size, cred); + error = VOP_LISTEXTATTR(vp, attrnamespace, uio, size, flag, cred); rump_unschedule(); return error; Index: src/sys/sys/extattr.h diff -u src/sys/sys/extattr.h:1.5 src/sys/sys/extattr.h:1.6 --- src/sys/sys/extattr.h:1.5 Fri Jun 17 14:23:51 2011 +++ src/sys/sys/extattr.h Mon Jul 4 08:07:31 2011 @@ -1,4 +1,4 @@ -/* $NetBSD: extattr.h,v 1.5 2011/06/17 14:23:51 manu Exp $ */ +/* $NetBSD: extattr.h,v 1.6 2011/07/04 08:07:31 manu Exp $ */ /*- * Copyright (c) 1999-2001 Robert N. M. Watson @@ -54,6 +54,9 @@ #include <sys/syslimits.h> +/* VOP_LISTEXTATTR flags */ +#define EXTATTR_LIST_LENPREFIX 1 /* names with length prefix */ + #define EXTATTR_MAXNAMELEN NAME_MAX struct lwp; struct vnode; Index: src/sys/sys/vnode_if.h diff -u src/sys/sys/vnode_if.h:1.80 src/sys/sys/vnode_if.h:1.81 --- src/sys/sys/vnode_if.h:1.80 Sun Mar 6 17:08:38 2011 +++ src/sys/sys/vnode_if.h Mon Jul 4 08:07:31 2011 @@ -1,4 +1,4 @@ -/* $NetBSD: vnode_if.h,v 1.80 2011/03/06 17:08:38 bouyer Exp $ */ +/* $NetBSD: vnode_if.h,v 1.81 2011/07/04 08:07:31 manu Exp $ */ /* * Warning: DO NOT EDIT! This file is automatically generated! @@ -515,10 +515,12 @@ int a_attrnamespace; struct uio *a_uio; size_t *a_size; + int a_flag; kauth_cred_t a_cred; }; extern const struct vnodeop_desc vop_listextattr_desc; -int VOP_LISTEXTATTR(struct vnode *, int, struct uio *, size_t *, kauth_cred_t); +int VOP_LISTEXTATTR(struct vnode *, int, struct uio *, size_t *, + int, kauth_cred_t); #define VOP_OPENEXTATTR_DESCOFFSET 45 struct vop_openextattr_args { Index: src/sys/ufs/ufs/ufs_extattr.c diff -u src/sys/ufs/ufs/ufs_extattr.c:1.33 src/sys/ufs/ufs/ufs_extattr.c:1.34 --- src/sys/ufs/ufs/ufs_extattr.c:1.33 Mon Jun 27 16:34:47 2011 +++ src/sys/ufs/ufs/ufs_extattr.c Mon Jul 4 08:07:32 2011 @@ -1,4 +1,4 @@ -/* $NetBSD: ufs_extattr.c,v 1.33 2011/06/27 16:34:47 manu Exp $ */ +/* $NetBSD: ufs_extattr.c,v 1.34 2011/07/04 08:07:32 manu Exp $ */ /*- * Copyright (c) 1999-2002 Robert N. M. Watson @@ -48,7 +48,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: ufs_extattr.c,v 1.33 2011/06/27 16:34:47 manu Exp $"); +__KERNEL_RCSID(0, "$NetBSD: ufs_extattr.c,v 1.34 2011/07/04 08:07:32 manu Exp $"); #ifdef _KERNEL_OPT #include "opt_ffs.h" @@ -96,7 +96,7 @@ const char *name, struct uio *uio, size_t *size, kauth_cred_t cred, struct lwp *l); static int ufs_extattr_list(struct vnode *vp, int attrnamespace, - struct uio *uio, size_t *size, + struct uio *uio, size_t *size, int flag, kauth_cred_t cred, struct lwp *l); static int ufs_extattr_set(struct vnode *vp, int attrnamespace, const char *name, struct uio *uio, kauth_cred_t cred, @@ -1137,6 +1137,7 @@ IN int a_attrnamespace; INOUT struct uio *a_uio; OUT size_t *a_size; + IN int flag; IN kauth_cred_t a_cred; struct proc *a_p; }; @@ -1149,7 +1150,7 @@ ufs_extattr_uepm_lock(ump); error = ufs_extattr_list(ap->a_vp, ap->a_attrnamespace, - ap->a_uio, ap->a_size, ap->a_cred, curlwp); + ap->a_uio, ap->a_size, ap->a_flag, ap->a_cred, curlwp); ufs_extattr_uepm_unlock(ump); @@ -1162,7 +1163,8 @@ */ static int ufs_extattr_list(struct vnode *vp, int attrnamespace, - struct uio *uio, size_t *size, kauth_cred_t cred, struct lwp *l) + struct uio *uio, size_t *size, int flag, + kauth_cred_t cred, struct lwp *l) { struct ufs_extattr_list_entry *uele; struct ufs_extattr_header ueh; @@ -1199,13 +1201,33 @@ vn_lock(uele->uele_backing_vnode, LK_SHARED | LK_RETRY); /* - * +1 for trailing \0 + * +1 for trailing NUL (listxattr flavor) + * or leading name length (extattr_list_file flavor) */ - attrnamelen = strlen(uele->uele_attrname) + 1; - listsize += attrnamelen; + attrnamelen = strlen(uele->uele_attrname); + listsize += attrnamelen + 1; /* Return data if the caller requested it. */ if (uio != NULL) { + /* + * We support two flavors. Either NUL-terminated + * strings (a la listxattr), or non NUL-terminated, + * one byte length prefixed strings (for + * extattr_list_file). EXTATTR_LIST_LENPREFIX switches + * that second behavior. + */ + if (flag & EXTATTR_LIST_LENPREFIX) { + uint8_t len = (uint8_t)attrnamelen; + + /* Copy leading name length */ + error = uiomove(&len, sizeof(len), uio); + if (error != 0) + break; + } else { + /* Include trailing NULL */ + attrnamelen++; + } + error = uiomove(uele->uele_attrname, (size_t)attrnamelen, uio); if (error != 0) Index: src/usr.bin/extattr/getextattr.c diff -u src/usr.bin/extattr/getextattr.c:1.6 src/usr.bin/extattr/getextattr.c:1.7 --- src/usr.bin/extattr/getextattr.c:1.6 Tue Jun 28 07:24:14 2011 +++ src/usr.bin/extattr/getextattr.c Mon Jul 4 08:07:32 2011 @@ -1,4 +1,4 @@ -/* $NetBSD: getextattr.c,v 1.6 2011/06/28 07:24:14 manu Exp $ */ +/* $NetBSD: getextattr.c,v 1.7 2011/07/04 08:07:32 manu Exp $ */ /*- * Copyright (c) 2002, 2003 Networks Associates Technology, Inc. @@ -237,8 +237,9 @@ break; if (!flag_quiet) printf("%s\t", argv[arg_counter]); - for (i = 0; i < error; i += strlen(buf + i) + 1) - printf("%s%s", i ? "\t" : "", buf + i); + for (i = 0; i < error; i += buf[i] + 1) + printf("%s%*.*s", i ? "\t" : "", + buf[i], buf[i], buf + i + 1); printf("\n"); continue; case EAGET: