From bec30953cdbbb03d2a3791bd1ffe5b062bad0ec3 Mon Sep 17 00:00:00 2001 From: Gunnar Beutner Date: Sun, 17 Apr 2011 20:31:33 +0200 Subject: [PATCH] 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 Closes #203 --- module/zfs/zpl_xattr.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) 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;