X-Git-Url: https://git.carlh.net/gitweb/?a=blobdiff_plain;f=lwext4%2Fext4_xattr.c;h=db5081513ee906298ecd90572dcbd09befa29d39;hb=d15d9a8f91b8cf071c8d635d4643789104a3dcd8;hp=9491e9a937e2a6de4142071aa06a51fecf164079;hpb=a1a24db03c42c2f6af2aa97dc9a145dbb03559e2;p=lwext4.git diff --git a/lwext4/ext4_xattr.c b/lwext4/ext4_xattr.c index 9491e9a..db50815 100644 --- a/lwext4/ext4_xattr.c +++ b/lwext4/ext4_xattr.c @@ -371,11 +371,18 @@ ext4_xattr_insert_item(struct ext4_xattr_ref *xattr_ref, uint8_t name_index, if (!item) return NULL; - if (xattr_ref->ea_size + EXT4_XATTR_SIZE(item->data_size) + + if ((xattr_ref->ea_size + EXT4_XATTR_SIZE(data_size) + + EXT4_XATTR_LEN(item->name_len) + > + ext4_xattr_inode_space(xattr_ref) - + sizeof(struct ext4_xattr_ibody_header)) + && + (xattr_ref->ea_size + EXT4_XATTR_SIZE(data_size) + EXT4_XATTR_LEN(item->name_len) > - ext4_xattr_inode_space(xattr_ref) + - ext4_xattr_block_space(xattr_ref)) { + ext4_xattr_block_space(xattr_ref) - + sizeof(struct ext4_xattr_header))) { ext4_xattr_item_free(item); + return NULL; } if (ext4_xattr_item_alloc_data(item, data, data_size) != EOK) { @@ -401,10 +408,11 @@ static int ext4_xattr_remove_item(struct ext4_xattr_ref *xattr_ref, 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); + + RB_REMOVE(ext4_xattr_tree, &xattr_ref->root, item); + ext4_xattr_item_free(item); xattr_ref->dirty = true; ret = EOK; } @@ -416,10 +424,18 @@ static int ext4_xattr_resize_item(struct ext4_xattr_ref *xattr_ref, 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)) { + size_t old_data_size = item->data_size; + if ((xattr_ref->ea_size - EXT4_XATTR_SIZE(old_data_size) + + EXT4_XATTR_SIZE(new_data_size) + > + ext4_xattr_inode_space(xattr_ref) - + sizeof(struct ext4_xattr_ibody_header)) + && + (xattr_ref->ea_size - EXT4_XATTR_SIZE(old_data_size) + + EXT4_XATTR_SIZE(new_data_size) + > + ext4_xattr_block_space(xattr_ref) - + sizeof(struct ext4_xattr_header))) { return ENOSPC; } @@ -427,8 +443,10 @@ static int ext4_xattr_resize_item(struct ext4_xattr_ref *xattr_ref, if (ret != EOK) { return ret; } - xattr_ref->ea_size -= - EXT4_XATTR_SIZE(item->data_size) + EXT4_XATTR_SIZE(new_data_size); + xattr_ref->ea_size = + xattr_ref->ea_size - + EXT4_XATTR_SIZE(old_data_size) + + EXT4_XATTR_SIZE(new_data_size); xattr_ref->dirty = true; return ret; } @@ -436,20 +454,12 @@ static int ext4_xattr_resize_item(struct ext4_xattr_ref *xattr_ref, static void ext4_xattr_purge_items(struct ext4_xattr_ref *xattr_ref) { struct ext4_xattr_item *item, *save_item; - uint64_t xattr_block = ext4_inode_get_file_acl( - xattr_ref->inode_ref->inode, &xattr_ref->fs->sb); RB_FOREACH_SAFE(item, ext4_xattr_tree, &xattr_ref->root, save_item) { RB_REMOVE(ext4_xattr_tree, &xattr_ref->root, item); ext4_xattr_item_free(item); } xattr_ref->ea_size = 0; - if (xattr_block) - xattr_ref->ea_size += sizeof(struct ext4_xattr_header); - - if (ext4_xattr_inode_space(xattr_ref) > - sizeof(struct ext4_xattr_ibody_header)) - xattr_ref->ea_size += sizeof(struct ext4_xattr_ibody_header); } static int ext4_xattr_try_alloc_block(struct ext4_xattr_ref *xattr_ref) @@ -477,7 +487,6 @@ static int ext4_xattr_try_alloc_block(struct ext4_xattr_ref *xattr_ref) &xattr_ref->fs->sb, xattr_block); xattr_ref->inode_ref->dirty = true; xattr_ref->block_loaded = true; - xattr_ref->ea_size += sizeof(struct ext4_xattr_header); } Finish: @@ -495,7 +504,6 @@ static void ext4_xattr_try_free_block(struct ext4_xattr_ref *xattr_ref) ext4_balloc_free_block(xattr_ref->inode_ref, xattr_block); xattr_ref->inode_ref->dirty = true; xattr_ref->block_loaded = false; - xattr_ref->ea_size -= sizeof(struct ext4_xattr_header); } static void ext4_xattr_set_block_header(struct ext4_xattr_ref *xattr_ref) @@ -691,7 +699,7 @@ int ext4_fs_set_xattr(struct ext4_xattr_ref *ref, uint8_t name_index, ext4_xattr_lookup_item(ref, name_index, name, name_len); if (replace) { if (!item) { - ret = ENOATTR; + ret = ENODATA; goto Finish; } if (item->data_size != data_size) @@ -731,7 +739,7 @@ int ext4_fs_get_xattr(struct ext4_xattr_ref *ref, uint8_t name_index, ext4_xattr_lookup_item(ref, name_index, name, name_len); if (!item) { - ret = ENOATTR; + ret = ENODATA; goto Finish; } item_size = item->data_size; @@ -762,7 +770,6 @@ int ext4_fs_get_xattr_ref(struct ext4_fs *fs, struct ext4_inode_ref *inode_ref, if (rc != EOK) return EIO; - ref->ea_size += sizeof(struct ext4_xattr_header); ref->block_loaded = true; } else ref->block_loaded = false; @@ -770,10 +777,6 @@ int ext4_fs_get_xattr_ref(struct ext4_fs *fs, struct ext4_inode_ref *inode_ref, ref->inode_ref = inode_ref; ref->fs = fs; - if (ext4_xattr_inode_space(ref) > - sizeof(struct ext4_xattr_ibody_header)) - ref->ea_size += sizeof(struct ext4_xattr_ibody_header); - rc = ext4_xattr_fetch(ref); if (rc != EOK) { ext4_xattr_purge_items(ref);