diff options
-rw-r--r-- | sys/kern/vfs_extattr.c | 3 | ||||
-rw-r--r-- | sys/kern/vfs_syscalls.c | 3 | ||||
-rw-r--r-- | sys/kern/vfs_vnops.c | 2 | ||||
-rw-r--r-- | sys/kern/vnode_if.src | 4 | ||||
-rw-r--r-- | sys/ufs/ffs/ffs_vnops.c | 169 | ||||
-rw-r--r-- | sys/ufs/ufs/extattr.h | 1 | ||||
-rw-r--r-- | sys/ufs/ufs/ufs_extattr.c | 47 | ||||
-rw-r--r-- | sys/ufs/ufs/ufs_vnops.c | 3 |
8 files changed, 176 insertions, 56 deletions
diff --git a/sys/kern/vfs_extattr.c b/sys/kern/vfs_extattr.c index f04664f..4ac48b3 100644 --- a/sys/kern/vfs_extattr.c +++ b/sys/kern/vfs_extattr.c @@ -4258,7 +4258,8 @@ extattr_delete_vp(struct vnode *vp, int attrnamespace, const char *attrname, goto done; #endif - error = VOP_RMEXTATTR(vp, attrnamespace, attrname, td->td_ucred, td); + error = VOP_DELETEEXTATTR(vp, attrnamespace, attrname, td->td_ucred, + td); if (error == EOPNOTSUPP) error = VOP_SETEXTATTR(vp, attrnamespace, attrname, NULL, td->td_ucred, td); diff --git a/sys/kern/vfs_syscalls.c b/sys/kern/vfs_syscalls.c index f04664f..4ac48b3 100644 --- a/sys/kern/vfs_syscalls.c +++ b/sys/kern/vfs_syscalls.c @@ -4258,7 +4258,8 @@ extattr_delete_vp(struct vnode *vp, int attrnamespace, const char *attrname, goto done; #endif - error = VOP_RMEXTATTR(vp, attrnamespace, attrname, td->td_ucred, td); + error = VOP_DELETEEXTATTR(vp, attrnamespace, attrname, td->td_ucred, + td); if (error == EOPNOTSUPP) error = VOP_SETEXTATTR(vp, attrnamespace, attrname, NULL, td->td_ucred, td); diff --git a/sys/kern/vfs_vnops.c b/sys/kern/vfs_vnops.c index 9efbf6b..b60ac4c 100644 --- a/sys/kern/vfs_vnops.c +++ b/sys/kern/vfs_vnops.c @@ -1151,7 +1151,7 @@ vn_extattr_rm(struct vnode *vp, int ioflg, int attrnamespace, } /* authorize attribute removal as kernel */ - error = VOP_RMEXTATTR(vp, attrnamespace, attrname, NULL, td); + error = VOP_DELETEEXTATTR(vp, attrnamespace, attrname, NULL, td); if (error == EOPNOTSUPP) error = VOP_SETEXTATTR(vp, attrnamespace, attrname, NULL, NULL, td); diff --git a/sys/kern/vnode_if.src b/sys/kern/vnode_if.src index a00f3a8..17ee814 100644 --- a/sys/kern/vnode_if.src +++ b/sys/kern/vnode_if.src @@ -573,9 +573,9 @@ vop_openextattr { }; # -#% rmextattr vp L L L +#% deleteextattr vp L L L # -vop_rmextattr { +vop_deleteextattr { IN struct vnode *vp; IN int attrnamespace; IN const char *name; diff --git a/sys/ufs/ffs/ffs_vnops.c b/sys/ufs/ffs/ffs_vnops.c index 1541523..3157792 100644 --- a/sys/ufs/ffs/ffs_vnops.c +++ b/sys/ufs/ffs/ffs_vnops.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002 Networks Associates Technology, Inc. + * Copyright (c) 2002, 2003 Networks Associates Technology, Inc. * All rights reserved. * * This software was developed for the FreeBSD Project by Marshall @@ -91,6 +91,7 @@ static int ffs_extwrite(struct vnode *vp, struct uio *uio, int ioflag, struct ucred *cred); static int ffsext_strategy(struct vop_strategy_args *); static int ffs_closeextattr(struct vop_closeextattr_args *); +static int ffs_deleteextattr(struct vop_deleteextattr_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 *); @@ -107,6 +108,7 @@ static struct vnodeopv_entry_desc ffs_vnodeop_entries[] = { { &vop_reallocblks_desc, (vop_t *) ffs_reallocblks }, { &vop_write_desc, (vop_t *) ffs_write }, { &vop_closeextattr_desc, (vop_t *) ffs_closeextattr }, + { &vop_deleteextattr_desc, (vop_t *) ffs_deleteextattr }, { &vop_getextattr_desc, (vop_t *) ffs_getextattr }, { &vop_listextattr_desc, (vop_t *) ffs_listextattr }, { &vop_openextattr_desc, (vop_t *) ffs_openextattr }, @@ -123,6 +125,7 @@ static struct vnodeopv_entry_desc ffs_specop_entries[] = { { &vop_reallocblks_desc, (vop_t *) ffs_reallocblks }, { &vop_strategy_desc, (vop_t *) ffsext_strategy }, { &vop_closeextattr_desc, (vop_t *) ffs_closeextattr }, + { &vop_deleteextattr_desc, (vop_t *) ffs_deleteextattr }, { &vop_getextattr_desc, (vop_t *) ffs_getextattr }, { &vop_listextattr_desc, (vop_t *) ffs_listextattr }, { &vop_openextattr_desc, (vop_t *) ffs_openextattr }, @@ -139,6 +142,7 @@ static struct vnodeopv_entry_desc ffs_fifoop_entries[] = { { &vop_reallocblks_desc, (vop_t *) ffs_reallocblks }, { &vop_strategy_desc, (vop_t *) ffsext_strategy }, { &vop_closeextattr_desc, (vop_t *) ffs_closeextattr }, + { &vop_deleteextattr_desc, (vop_t *) ffs_deleteextattr }, { &vop_getextattr_desc, (vop_t *) ffs_getextattr }, { &vop_listextattr_desc, (vop_t *) ffs_listextattr }, { &vop_openextattr_desc, (vop_t *) ffs_openextattr }, @@ -1462,7 +1466,94 @@ struct vop_closeextattr_args { return (ffs_close_ea(ap->a_vp, ap->a_commit, ap->a_cred, ap->a_td)); } +/* + * Vnode operation to remove a named attribute. + */ +static int +ffs_deleteextattr(struct vop_deleteextattr_args *ap) +/* +vop_deleteextattr { + IN struct vnode *a_vp; + IN int a_attrnamespace; + IN const char *a_name; + IN struct ucred *a_cred; + IN struct thread *a_td; +}; +*/ +{ + struct inode *ip; + struct fs *fs; + uint32_t ealength, ul; + int ealen, olen, eapad1, eapad2, error, i, easize; + u_char *eae, *p; + int 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); + + 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) { + if (ip->i_ea_area != NULL && ip->i_ea_error == 0) + ip->i_ea_error = 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; + } + + ealength = eapad1 = ealen = eapad2 = 0; + + eae = malloc(ip->i_ea_len, M_TEMP, M_WAITOK); + bcopy(ip->i_ea_area, eae, ip->i_ea_len); + easize = ip->i_ea_len; + + olen = ffs_findextattr(eae, easize, ap->a_attrnamespace, ap->a_name, + &p, NULL); + if (olen == -1) { + /* delete but nonexistent */ + free(eae, M_TEMP); + if (stand_alone) + ffs_close_ea(ap->a_vp, 0, ap->a_cred, ap->a_td); + return(ENOATTR); + } + bcopy(p, &ul, sizeof ul); + i = p - eae + ul; + if (ul != ealength) { + bcopy(p + ul, p + ealength, easize - i); + easize += (ealength - ul); + } + if (easize > NXADDR * fs->fs_bsize) { + free(eae, M_TEMP); + if (stand_alone) + ffs_close_ea(ap->a_vp, 0, ap->a_cred, ap->a_td); + else if (ip->i_ea_error == 0) + ip->i_ea_error = ENOSPC; + return(ENOSPC); + } + p = ip->i_ea_area; + ip->i_ea_area = eae; + ip->i_ea_len = easize; + free(p, M_TEMP); + if (stand_alone) + error = ffs_close_ea(ap->a_vp, 1, ap->a_cred, ap->a_td); + return(error); +} /* * Vnode operation to retrieve a named extended attribute. @@ -1635,6 +1726,10 @@ vop_setextattr { if (strlen(ap->a_name) == 0) return (EINVAL); + /* XXX Now unsupported API to delete EAs using NULL uio. */ + if (ap->a_uio == NULL) + return (EOPNOTSUPP); + error = extattr_check_cred(ap->a_vp, ap->a_attrnamespace, ap->a_cred, ap->a_td, IWRITE); if (error) { @@ -1652,21 +1747,15 @@ vop_setextattr { stand_alone = 0; } - /* Calculate the length of the EA entry */ - if (ap->a_uio == NULL) { - /* delete */ - ealength = eapad1 = ealen = eapad2 = 0; - } else { - ealen = ap->a_uio->uio_resid; - ealength = sizeof(uint32_t) + 3 + strlen(ap->a_name); - eapad1 = 8 - (ealength % 8); - if (eapad1 == 8) - eapad1 = 0; - eapad2 = 8 - (ealen % 8); - if (eapad2 == 8) - eapad2 = 0; - ealength += eapad1 + ealen + eapad2; - } + ealen = ap->a_uio->uio_resid; + ealength = sizeof(uint32_t) + 3 + strlen(ap->a_name); + eapad1 = 8 - (ealength % 8); + if (eapad1 == 8) + eapad1 = 0; + eapad2 = 8 - (ealen % 8); + if (eapad2 == 8) + eapad2 = 0; + ealength += eapad1 + ealen + eapad2; eae = malloc(ip->i_ea_len + ealength, M_TEMP, M_WAITOK); bcopy(ip->i_ea_area, eae, ip->i_ea_len); @@ -1674,13 +1763,6 @@ vop_setextattr { olen = ffs_findextattr(eae, easize, ap->a_attrnamespace, ap->a_name, &p, NULL); - if (olen == -1 && ealength == 0) { - /* delete but nonexistent */ - free(eae, M_TEMP); - if (stand_alone) - ffs_close_ea(ap->a_vp, 0, ap->a_cred, ap->a_td); - return(ENOATTR); - } if (olen == -1) { /* new, append at end */ p = eae + easize; @@ -1701,28 +1783,27 @@ vop_setextattr { ip->i_ea_error = ENOSPC; return(ENOSPC); } - if (ealength != 0) { - bcopy(&ealength, p, sizeof(ealength)); - p += sizeof(ealength); - *p++ = ap->a_attrnamespace; - *p++ = eapad2; - *p++ = strlen(ap->a_name); - strcpy(p, ap->a_name); - p += strlen(ap->a_name); - bzero(p, eapad1); - p += eapad1; - error = uiomove(p, ealen, ap->a_uio); - if (error) { - free(eae, M_TEMP); - if (stand_alone) - ffs_close_ea(ap->a_vp, 0, ap->a_cred, ap->a_td); - else if (ip->i_ea_error == 0) - ip->i_ea_error = error; - return(error); - } - p += ealen; - bzero(p, eapad2); + bcopy(&ealength, p, sizeof(ealength)); + p += sizeof(ealength); + *p++ = ap->a_attrnamespace; + *p++ = eapad2; + *p++ = strlen(ap->a_name); + strcpy(p, ap->a_name); + p += strlen(ap->a_name); + bzero(p, eapad1); + p += eapad1; + error = uiomove(p, ealen, ap->a_uio); + if (error) { + free(eae, M_TEMP); + if (stand_alone) + ffs_close_ea(ap->a_vp, 0, ap->a_cred, ap->a_td); + else if (ip->i_ea_error == 0) + ip->i_ea_error = error; + return(error); } + p += ealen; + bzero(p, eapad2); + p = ip->i_ea_area; ip->i_ea_area = eae; ip->i_ea_len = easize; diff --git a/sys/ufs/ufs/extattr.h b/sys/ufs/ufs/extattr.h index 9673690..cf32227 100644 --- a/sys/ufs/ufs/extattr.h +++ b/sys/ufs/ufs/extattr.h @@ -102,6 +102,7 @@ int ufs_extattr_stop(struct mount *mp, struct thread *td); int ufs_extattrctl(struct mount *mp, int cmd, struct vnode *filename, int attrnamespace, const char *attrname, struct thread *td); int ufs_getextattr(struct vop_getextattr_args *ap); +int ufs_deleteextattr(struct vop_deleteextattr_args *ap); int ufs_setextattr(struct vop_setextattr_args *ap); void ufs_extattr_vnode_inactive(struct vnode *vp, struct thread *td); diff --git a/sys/ufs/ufs/ufs_extattr.c b/sys/ufs/ufs/ufs_extattr.c index 8819698..bd87f0e 100644 --- a/sys/ufs/ufs/ufs_extattr.c +++ b/sys/ufs/ufs/ufs_extattr.c @@ -1,6 +1,6 @@ /*- * Copyright (c) 1999, 2000, 2001, 2002 Robert N. M. Watson - * Copyright (c) 2002 Networks Associates Technology, Inc. + * Copyright (c) 2002, 2003 Networks Associates Technology, Inc. * All rights reserved. * * This software was developed by Robert Watson for the TrustedBSD Project. @@ -964,6 +964,37 @@ vopunlock_exit: } /* + * Vnode operation to remove a named attribute. + */ +int +ufs_deleteextattr(struct vop_deleteextattr_args *ap) +/* +vop_deleteextattr { + IN struct vnode *a_vp; + IN int a_attrnamespace; + IN const char *a_name; + IN struct ucred *a_cred; + IN struct thread *a_td; +}; +*/ +{ + struct mount *mp = ap->a_vp->v_mount; + struct ufsmount *ump = VFSTOUFS(mp); + + int error; + + ufs_extattr_uepm_lock(ump, ap->a_td); + + error = ufs_extattr_rm(ap->a_vp, ap->a_attrnamespace, ap->a_name, + ap->a_cred, ap->a_td); + + + ufs_extattr_uepm_unlock(ump, ap->a_td); + + return (error); +} + +/* * Vnode operation to set a named attribute. */ int @@ -986,12 +1017,14 @@ vop_setextattr { ufs_extattr_uepm_lock(ump, ap->a_td); - if (ap->a_uio != NULL) - error = ufs_extattr_set(ap->a_vp, ap->a_attrnamespace, - ap->a_name, ap->a_uio, ap->a_cred, ap->a_td); - else - error = ufs_extattr_rm(ap->a_vp, ap->a_attrnamespace, - ap->a_name, ap->a_cred, ap->a_td); + /* + * XXX: No longer a supported way to delete extended attributes. + */ + if (ap->a_uio == NULL) + return (EINVAL); + + error = ufs_extattr_set(ap->a_vp, ap->a_attrnamespace, ap->a_name, + ap->a_uio, ap->a_cred, ap->a_td); ufs_extattr_uepm_unlock(ump, ap->a_td); diff --git a/sys/ufs/ufs/ufs_vnops.c b/sys/ufs/ufs/ufs_vnops.c index 1608260..971fce1 100644 --- a/sys/ufs/ufs/ufs_vnops.c +++ b/sys/ufs/ufs/ufs_vnops.c @@ -2703,6 +2703,7 @@ static struct vnodeopv_entry_desc ufs_vnodeop_entries[] = { { &vop_whiteout_desc, (vop_t *) ufs_whiteout }, #ifdef UFS_EXTATTR { &vop_getextattr_desc, (vop_t *) ufs_getextattr }, + { &vop_deleteextattr_desc, (vop_t *) ufs_deleteextattr }, { &vop_setextattr_desc, (vop_t *) ufs_setextattr }, #endif #ifdef UFS_ACL @@ -2733,6 +2734,7 @@ static struct vnodeopv_entry_desc ufs_specop_entries[] = { { &vop_write_desc, (vop_t *) ufsspec_write }, #ifdef UFS_EXTATTR { &vop_getextattr_desc, (vop_t *) ufs_getextattr }, + { &vop_deleteextattr_desc, (vop_t *) ufs_deleteextattr }, { &vop_setextattr_desc, (vop_t *) ufs_setextattr }, #endif #ifdef UFS_ACL @@ -2764,6 +2766,7 @@ static struct vnodeopv_entry_desc ufs_fifoop_entries[] = { { &vop_write_desc, (vop_t *) ufsfifo_write }, #ifdef UFS_EXTATTR { &vop_getextattr_desc, (vop_t *) ufs_getextattr }, + { &vop_deleteextattr_desc, (vop_t *) ufs_deleteextattr }, { &vop_setextattr_desc, (vop_t *) ufs_setextattr }, #endif #ifdef UFS_ACL |