struct rb_node *parent = NULL;
struct ceph_inode_xattr *xattr = NULL;
int c;
+ int new = 0;
p = &ci->i_xattrs.rb_node;
while (*p) {
}
if (!xattr) {
+ new = 1;
xattr = kmalloc(sizeof(*xattr), GFP_NOFS);
xattr->name = name;
xattr->name_len = name_len;
kfree((void *)xattr->val);
if (should_free_name) {
- kfree((void *)xattr->name);
+ kfree((void *)name);
+ name = xattr->name;
}
ci->i_xattr_names_size -= (xattr->name_len + 1);
}
xattr->dirty = dirty;
xattr->should_free_val = (val && should_free_val);
- rb_link_node(&xattr->node, parent, p);
- rb_insert_color(&xattr->node, &ci->i_xattrs);
+ if (new) {
+ rb_link_node(&xattr->node, parent, p);
+ rb_insert_color(&xattr->node, &ci->i_xattrs);
+ }
- dout(20, "__set_xattr_val added %llx.%llx xattr %s=%s\n",
- ceph_vinop(&ci->vfs_inode), name, val);
+ dout(0, "__set_xattr_val added %llx.%llx xattr %p %s=%s\n",
+ ceph_vinop(&ci->vfs_inode), xattr, name, val);
return 0;
}
memcpy(dest, xattr->name, xattr->name_len + 1);
+ dout(0, "dest=%s %p (%s) (%d/%d)\n", dest, xattr, xattr->name, xattr->name_len, ci->i_xattr_names_size);
+
dest += xattr->name_len + 1;
p = rb_next(p);
struct ceph_inode_info *ci = ceph_inode(inode);
u32 vir_namelen = 0;
u32 namelen;
- void *p;
int err;
u32 len;
int i;
if (size == 0)
goto out;
- p = __copy_xattr_names(ci, names);
+ names = __copy_xattr_names(ci, names);
/* virtual xattr names, too */
if ((inode->i_mode & S_IFMT) == S_IFDIR)
newname = kmalloc(name_len + 1, GFP_NOFS);
if (IS_ERR(newname)) {
err = PTR_ERR(newname);
- goto done;
+ goto out;
}
memcpy(newname, name, name_len + 1);
newval = kmalloc(val_len + 1, GFP_NOFS);
if (IS_ERR(newval)) {
err = PTR_ERR(newval);
- goto done;
+ goto out;
}
- memcpy(newval, value, val_len + 1);
+ memcpy(newval, value, val_len);
+ newval[val_len] = '\0';
}
dout(0, "setxattr newname=%s\n", newname);
spin_unlock(&inode->i_lock);
err = ceph_send_setxattr(dentry, value, size, flags);
-done:
+
+ return err;
+out:
kfree(newname);
return err;
}