summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--sys/kern/vfs_extattr.c3
-rw-r--r--sys/kern/vfs_syscalls.c3
-rw-r--r--sys/kern/vfs_vnops.c2
-rw-r--r--sys/kern/vnode_if.src4
-rw-r--r--sys/ufs/ffs/ffs_vnops.c169
-rw-r--r--sys/ufs/ufs/extattr.h1
-rw-r--r--sys/ufs/ufs/ufs_extattr.c47
-rw-r--r--sys/ufs/ufs/ufs_vnops.c3
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
OpenPOWER on IntegriCloud