diff options
author | rwatson <rwatson@FreeBSD.org> | 2003-06-05 05:57:39 +0000 |
---|---|---|
committer | rwatson <rwatson@FreeBSD.org> | 2003-06-05 05:57:39 +0000 |
commit | 563547c6bcea9af43fe8c4bb2ee678ffbbf6efb7 (patch) | |
tree | 8239ffb23313ec8f91f4537c8ef02acc9023ea1f /sys/ufs | |
parent | 6b8a71ea4a26e2a16ffaecf323e0f05dec56fd1a (diff) | |
download | FreeBSD-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.c | 120 |
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) { |