/* Manipulate the contents of extended attribute regions */
struct ext2_xattr {
+ int name_index;
char *name;
+ char *short_name;
void *value;
unsigned int value_len;
ext2_ino_t ea_ino;
struct ext2_xattr *x;
struct ext2_ext_attr_entry *e = entries_start;
char *end = (char *) entries_start + storage_size;
- const char *shortname;
unsigned int value_size;
- int idx, ret;
errcode_t err;
memset(entries_start, 0, storage_size);
for (x = attrs; x < attrs + count; x++) {
- /* Calculate index and shortname position */
- shortname = x->name;
- ret = find_ea_index(x->name, &shortname, &idx);
-
value_size = ((x->value_len + EXT2_EXT_ATTR_PAD - 1) /
EXT2_EXT_ATTR_PAD) * EXT2_EXT_ATTR_PAD;
/* Fill out e appropriately */
- e->e_name_len = strlen(shortname);
- e->e_name_index = (ret ? idx : 0);
+ e->e_name_len = strlen(x->short_name);
+ e->e_name_index = x->name_index;
e->e_value_size = x->value_len;
e->e_value_inum = x->ea_ino;
/* Store name */
- memcpy((char *)e + sizeof(*e), shortname, e->e_name_len);
+ memcpy((char *)e + sizeof(*e), x->short_name, e->e_name_len);
if (x->ea_ino) {
e->e_value_offs = 0;
} else {
memcpy(x->name + prefix_len,
(char *)entry + sizeof(*entry),
entry->e_name_len);
+ x->short_name = x->name + prefix_len;
+ x->name_index = entry->e_name_index;
/* Check & copy value */
if (!ext2fs_has_feature_ea_inode(handle->fs->super) &&
}
static errcode_t xattr_update_entry(ext2_filsys fs, struct ext2_xattr *x,
- const char *name, const void *value,
+ const char *name, const char *short_name,
+ int index, const void *value,
size_t value_len, int in_inode)
{
ext2_ino_t ea_ino = 0;
goto fail;
}
- if (!x->name)
+ if (!x->name) {
x->name = new_name;
+ x->short_name = new_name + (short_name - name);
+ }
+ x->name_index = index;
if (x->value)
ext2fs_free_mem(&x->value);
}
static int xattr_find_position(struct ext2_xattr *attrs, int count,
- const char *name)
+ const char *shortname, int name_idx)
{
struct ext2_xattr *x;
int i;
- const char *shortname, *x_shortname;
- int name_idx, x_name_idx;
int shortname_len, x_shortname_len;
- find_ea_index(name, &shortname, &name_idx);
shortname_len = strlen(shortname);
for (i = 0, x = attrs; i < count; i++, x++) {
- find_ea_index(x->name, &x_shortname, &x_name_idx);
- if (name_idx < x_name_idx)
+ if (name_idx < x->name_index)
break;
- if (name_idx > x_name_idx)
+ if (name_idx > x->name_index)
continue;
- x_shortname_len = strlen(x_shortname);
+ x_shortname_len = strlen(x->short_name);
if (shortname_len < x_shortname_len)
break;
if (shortname_len > x_shortname_len)
continue;
- if (memcmp(shortname, x_shortname, shortname_len) <= 0)
+ if (memcmp(shortname, x->short_name, shortname_len) <= 0)
break;
}
return i;
struct ext2_xattr tmp;
int add_to_ibody;
int needed;
- int name_len, name_idx;
- const char *shortname;
+ int name_len, name_idx = 0;
+ const char *shortname = name;
int new_idx;
int ret;
/* Update the existing entry. */
ret = xattr_update_entry(h->fs, &h->attrs[old_idx], name,
- value, value_len, in_inode);
+ shortname, name_idx, value,
+ value_len, in_inode);
if (ret)
return ret;
if (h->ibody_count <= old_idx) {
if (old_idx >= 0) {
/* Update the existing entry. */
ret = xattr_update_entry(h->fs, &h->attrs[old_idx], name,
- value, value_len, in_inode);
+ shortname, name_idx, value,
+ value_len, in_inode);
if (ret)
return ret;
if (old_idx < h->ibody_count) {
* entries in the block are sorted.
*/
new_idx = xattr_find_position(h->attrs + h->ibody_count,
- h->count - h->ibody_count, name);
+ h->count - h->ibody_count,
+ shortname, name_idx);
new_idx += h->ibody_count - 1;
tmp = h->attrs[old_idx];
memmove(h->attrs + old_idx, h->attrs + old_idx + 1,
}
new_idx = xattr_find_position(h->attrs + h->ibody_count,
- h->count - h->ibody_count, name);
+ h->count - h->ibody_count,
+ shortname, name_idx);
new_idx += h->ibody_count;
add_to_ibody = 0;
return ret;
}
- ret = xattr_update_entry(h->fs, &h->attrs[h->count], name, value,
- value_len, in_inode);
+ ret = xattr_update_entry(h->fs, &h->attrs[h->count], name, shortname,
+ name_idx, value, value_len, in_inode);
if (ret)
return ret;
{
int total = 0;
struct ext2_xattr *x;
- const char *shortname;
- int i, len, name_idx;
+ int i, len;
for (i = 0, x = attrs; i < count; i++, x++) {
- find_ea_index(x->name, &shortname, &name_idx);
- len = strlen(shortname);
+ len = strlen(x->short_name);
total += EXT2_EXT_ATTR_LEN(len);
if (!x->ea_ino)
total += EXT2_EXT_ATTR_SIZE(x->value_len);