summaryrefslogtreecommitdiffstats
path: root/sys/ufs
diff options
context:
space:
mode:
authorrwatson <rwatson@FreeBSD.org>2003-06-05 05:57:39 +0000
committerrwatson <rwatson@FreeBSD.org>2003-06-05 05:57:39 +0000
commit563547c6bcea9af43fe8c4bb2ee678ffbbf6efb7 (patch)
tree8239ffb23313ec8f91f4537c8ef02acc9023ea1f /sys/ufs
parent6b8a71ea4a26e2a16ffaecf323e0f05dec56fd1a (diff)
downloadFreeBSD-src-563547c6bcea9af43fe8c4bb2ee678ffbbf6efb7.zip
FreeBSD-src-563547c6bcea9af43fe8c4bb2ee678ffbbf6efb7.tar.gz
Implement ffs_listextattr() by breaking out that logic and special-cased
attribute name of "" from ffs_getextattr(). Invoking VOP_GETETATTR() with an empty name is now no longer supported; user application compatibility is provided by a system call level compatibility wrapper. We make sure to explicitly reject attempts to set an EA with the name "". Obtained from: TrustedBSD Project Sponsored by: DARPA, Network Associates Laboratories
Diffstat (limited to 'sys/ufs')
-rw-r--r--sys/ufs/ffs/ffs_vnops.c120
1 files changed, 88 insertions, 32 deletions
diff --git a/sys/ufs/ffs/ffs_vnops.c b/sys/ufs/ffs/ffs_vnops.c
index ab716c9..e56be2e 100644
--- a/sys/ufs/ffs/ffs_vnops.c
+++ b/sys/ufs/ffs/ffs_vnops.c
@@ -90,6 +90,7 @@ static int ffs_extwrite(struct vnode *vp, struct uio *uio, int ioflag,
static int ffsext_strategy(struct vop_strategy_args *);
static int ffs_closeextattr(struct vop_closeextattr_args *);
static int ffs_getextattr(struct vop_getextattr_args *);
+static int ffs_listextattr(struct vop_listextattr_args *);
static int ffs_openextattr(struct vop_openextattr_args *);
static int ffs_setextattr(struct vop_setextattr_args *);
@@ -105,6 +106,7 @@ static struct vnodeopv_entry_desc ffs_vnodeop_entries[] = {
{ &vop_write_desc, (vop_t *) ffs_write },
{ &vop_closeextattr_desc, (vop_t *) ffs_closeextattr },
{ &vop_getextattr_desc, (vop_t *) ffs_getextattr },
+ { &vop_listextattr_desc, (vop_t *) ffs_listextattr },
{ &vop_openextattr_desc, (vop_t *) ffs_openextattr },
{ &vop_setextattr_desc, (vop_t *) ffs_setextattr },
{ NULL, NULL }
@@ -120,6 +122,7 @@ static struct vnodeopv_entry_desc ffs_specop_entries[] = {
{ &vop_strategy_desc, (vop_t *) ffsext_strategy },
{ &vop_closeextattr_desc, (vop_t *) ffs_closeextattr },
{ &vop_getextattr_desc, (vop_t *) ffs_getextattr },
+ { &vop_listextattr_desc, (vop_t *) ffs_listextattr },
{ &vop_openextattr_desc, (vop_t *) ffs_openextattr },
{ &vop_setextattr_desc, (vop_t *) ffs_setextattr },
{ NULL, NULL }
@@ -135,6 +138,7 @@ static struct vnodeopv_entry_desc ffs_fifoop_entries[] = {
{ &vop_strategy_desc, (vop_t *) ffsext_strategy },
{ &vop_closeextattr_desc, (vop_t *) ffs_closeextattr },
{ &vop_getextattr_desc, (vop_t *) ffs_getextattr },
+ { &vop_listextattr_desc, (vop_t *) ffs_listextattr },
{ &vop_openextattr_desc, (vop_t *) ffs_openextattr },
{ &vop_setextattr_desc, (vop_t *) ffs_setextattr },
{ NULL, NULL }
@@ -1467,9 +1471,8 @@ vop_getextattr {
{
struct inode *ip;
struct fs *fs;
- u_char *eae, *p, *pe, *pn;
+ u_char *eae, *p;
unsigned easize;
- uint32_t ul;
int error, ealen, stand_alone;
ip = VTOI(ap->a_vp);
@@ -1496,38 +1499,88 @@ vop_getextattr {
}
eae = ip->i_ea_area;
easize = ip->i_ea_len;
- if (strlen(ap->a_name) > 0) {
- ealen = ffs_findextattr(eae, easize,
- ap->a_attrnamespace, ap->a_name, NULL, &p);
- if (ealen >= 0) {
- error = 0;
- if (ap->a_size != NULL)
- *ap->a_size = ealen;
- else if (ap->a_uio != NULL)
- error = uiomove(p, ealen, ap->a_uio);
- } else {
- error = ENOATTR;
- }
- } else {
+
+ ealen = ffs_findextattr(eae, easize, ap->a_attrnamespace, ap->a_name,
+ NULL, &p);
+ if (ealen >= 0) {
error = 0;
if (ap->a_size != NULL)
- *ap->a_size = 0;
- pe = eae + easize;
- for(p = eae; error == 0 && p < pe; p = pn) {
- bcopy(p, &ul, sizeof(ul));
- pn = p + ul;
- if (pn > pe)
- break;
- p += sizeof(ul);
- if (*p++ != ap->a_attrnamespace)
- continue;
- p++; /* pad2 */
- ealen = *p;
- if (ap->a_size != NULL) {
- *ap->a_size += ealen + 1;
- } else if (ap->a_uio != NULL) {
- error = uiomove(p, ealen + 1, ap->a_uio);
- }
+ *ap->a_size = ealen;
+ else if (ap->a_uio != NULL)
+ error = uiomove(p, ealen, ap->a_uio);
+ } else
+ error = ENOATTR;
+ if (stand_alone)
+ ffs_close_ea(ap->a_vp, 0, ap->a_cred, ap->a_td);
+ return(error);
+}
+
+/*
+ * Vnode operation to retrieve extended attributes on a vnode.
+ */
+static int
+ffs_listextattr(struct vop_listextattr_args *ap)
+/*
+vop_listextattr {
+ IN struct vnode *a_vp;
+ IN int a_attrnamespace;
+ INOUT struct uio *a_uio;
+ OUT size_t *a_size;
+ IN struct ucred *a_cred;
+ IN struct thread *a_td;
+};
+*/
+{
+ struct inode *ip;
+ struct fs *fs;
+ u_char *eae, *p, *pe, *pn;
+ unsigned easize;
+ uint32_t ul;
+ int error, ealen, stand_alone;
+
+ ip = VTOI(ap->a_vp);
+ fs = ip->i_fs;
+
+ if (fs->fs_magic == FS_UFS1_MAGIC)
+ return (ufs_vnoperate((struct vop_generic_args *)ap));
+
+ if (ap->a_vp->v_type == VCHR)
+ return (EOPNOTSUPP);
+
+ error = extattr_check_cred(ap->a_vp, ap->a_attrnamespace,
+ ap->a_cred, ap->a_td, IREAD);
+ if (error)
+ return (error);
+
+ if (ip->i_ea_area == NULL) {
+ error = ffs_open_ea(ap->a_vp, ap->a_cred, ap->a_td);
+ if (error)
+ return (error);
+ stand_alone = 1;
+ } else {
+ stand_alone = 0;
+ }
+ eae = ip->i_ea_area;
+ easize = ip->i_ea_len;
+
+ error = 0;
+ if (ap->a_size != NULL)
+ *ap->a_size = 0;
+ pe = eae + easize;
+ for(p = eae; error == 0 && p < pe; p = pn) {
+ bcopy(p, &ul, sizeof(ul));
+ pn = p + ul;
+ if (pn > pe)
+ break;
+ p += sizeof(ul);
+ if (*p++ != ap->a_attrnamespace)
+ continue;
+ p++; /* pad2 */
+ ealen = *p;
+ if (ap->a_size != NULL) {
+ *ap->a_size += ealen + 1;
+ } else if (ap->a_uio != NULL) {
+ error = uiomove(p, ealen + 1, ap->a_uio);
}
}
if (stand_alone)
@@ -1567,6 +1620,9 @@ vop_setextattr {
if (ap->a_vp->v_type == VCHR)
return (EOPNOTSUPP);
+ if (strlen(ap->a_name) == 0)
+ return (EINVAL);
+
error = extattr_check_cred(ap->a_vp, ap->a_attrnamespace,
ap->a_cred, ap->a_td, IWRITE);
if (error) {
OpenPOWER on IntegriCloud