diff options
author | Gunnar Beutner <[email protected]> | 2011-04-17 20:31:33 +0200 |
---|---|---|
committer | Brian Behlendorf <[email protected]> | 2011-04-19 14:14:40 -0700 |
commit | bec30953cdbbb03d2a3791bd1ffe5b062bad0ec3 (patch) | |
tree | f9bcae8d2924b4379079c8713ab9e061118672c8 /module/zfs/zpl_xattr.c | |
parent | 274b7e79f3baece5ab28331e73629f6e81fdb5ca (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
Diffstat (limited to 'module/zfs/zpl_xattr.c')
-rw-r--r-- | module/zfs/zpl_xattr.c | 8 |
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; |