summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGunnar Beutner <[email protected]>2011-04-17 20:31:33 +0200
committerBrian Behlendorf <[email protected]>2011-04-19 14:14:40 -0700
commitbec30953cdbbb03d2a3791bd1ffe5b062bad0ec3 (patch)
treef9bcae8d2924b4379079c8713ab9e061118672c8
parent274b7e79f3baece5ab28331e73629f6e81fdb5ca (diff)
Truncate the xattr znode when updating existing attributes.
If the attribute's new value was shorter than the old one the old code would leave parts of the old value in the xattr znode. Signed-off-by: Brian Behlendorf <[email protected]> Closes #203
-rw-r--r--module/zfs/zpl_xattr.c8
1 files changed, 7 insertions, 1 deletions
diff --git a/module/zfs/zpl_xattr.c b/module/zfs/zpl_xattr.c
index 82787cb2d..bb9341422 100644
--- a/module/zfs/zpl_xattr.c
+++ b/module/zfs/zpl_xattr.c
@@ -191,6 +191,7 @@ zpl_xattr_set(struct inode *ip, const char *name, const void *value,
cred_t *cr = CRED();
ssize_t wrote;
int error;
+ const int xattr_mode = S_IFREG | 0644;
crhold(cr);
@@ -230,7 +231,7 @@ zpl_xattr_set(struct inode *ip, const char *name, const void *value,
/* Lookup failed create a new xattr. */
if (xip == NULL) {
vap = kmem_zalloc(sizeof(vattr_t), KM_SLEEP);
- vap->va_mode = S_IFREG | 0644;
+ vap->va_mode = xattr_mode;
vap->va_mask = ATTR_MODE;
vap->va_uid = crgetfsuid(cr);
vap->va_gid = crgetfsgid(cr);
@@ -242,6 +243,11 @@ zpl_xattr_set(struct inode *ip, const char *name, const void *value,
}
ASSERT(xip != NULL);
+
+ error = -zfs_freesp(ITOZ(xip), 0, 0, xattr_mode, TRUE);
+ if (error)
+ goto out;
+
wrote = zpl_write_common(xip, value, size, 0, UIO_SYSSPACE, 0, cr);
if (wrote < 0)
error = wrote;