+static struct ext4_xattr_item *
+ext4_xattr_insert_item(struct ext4_xattr_ref *xattr_ref,
+ uint8_t name_index,
+ char *name,
+ size_t name_len,
+ void *data,
+ size_t data_size)
+{
+ struct ext4_xattr_item *item;
+ item = ext4_xattr_item_alloc(name_index,
+ name,
+ name_len);
+ if (!item)
+ return NULL;
+
+ if (xattr_ref->ea_size + EXT4_XATTR_SIZE(item->data_size) +
+ EXT4_XATTR_LEN(item->name_len) >
+ ext4_xattr_inode_space(xattr_ref) +
+ ext4_xattr_block_space(xattr_ref)) {
+ ext4_xattr_item_free(item);
+ return NULL;
+ }
+ if (ext4_xattr_item_alloc_data(item,
+ data,
+ data_size) != EOK) {
+ ext4_xattr_item_free(item);
+ return NULL;
+ }
+ RB_INSERT(ext4_xattr_tree, &xattr_ref->root, item);
+ xattr_ref->ea_size += EXT4_XATTR_SIZE(item->data_size) +
+ EXT4_XATTR_LEN(item->name_len);
+ xattr_ref->dirty = true;
+ return item;
+}
+
+static int
+ext4_xattr_remove_item(struct ext4_xattr_ref *xattr_ref,
+ uint8_t name_index,
+ char *name,
+ size_t name_len)
+{
+ int ret = ENOENT;
+ struct ext4_xattr_item *item =
+ ext4_xattr_lookup_item(xattr_ref,
+ name_index,
+ name,
+ name_len);
+ if (item) {
+ if (item == xattr_ref->iter_from)
+ xattr_ref->iter_from = RB_NEXT(ext4_xattr_tree,
+ &xattr_ref->root,
+ item);
+
+ RB_REMOVE(ext4_xattr_tree, &xattr_ref->root, item);
+ ext4_xattr_item_free(item);
+ xattr_ref->ea_size -= EXT4_XATTR_SIZE(item->data_size) +
+ EXT4_XATTR_LEN(item->name_len);
+ xattr_ref->dirty = true;
+ ret = EOK;
+ }
+ return ret;
+}
+
+static int
+ext4_xattr_resize_item(struct ext4_xattr_ref *xattr_ref,
+ struct ext4_xattr_item *item,
+ size_t new_data_size)
+{
+ int ret = EOK;
+ if (xattr_ref->ea_size - EXT4_XATTR_SIZE(item->data_size) +
+ EXT4_XATTR_SIZE(new_data_size) >
+ ext4_xattr_inode_space(xattr_ref) +
+ ext4_xattr_block_space(xattr_ref)) {
+
+ return ENOSPC;
+ }
+ ret = ext4_xattr_item_resize_data(item,
+ new_data_size);
+ if (ret != EOK) {
+ return ret;
+ }
+ xattr_ref->ea_size -= EXT4_XATTR_SIZE(item->data_size) +
+ EXT4_XATTR_SIZE(new_data_size);
+ xattr_ref->dirty = true;
+ return ret;
+}
+