summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorgkostka <kostka.grzegorz@gmail.com>2015-10-10 04:29:21 +0200
committergkostka <kostka.grzegorz@gmail.com>2015-10-10 04:29:21 +0200
commit59950cfeb06442b20ccebf9f0c94d5f35370ae15 (patch)
tree6f63cc2e0b1e41dbb4edf5c6d86bf05318fd5e59
parent9792c01efcf868269bab6cce4fa6efefcc1adcb6 (diff)
parenta4ec81fd03739007d083a7cc3bfaf5e548cefc8e (diff)
Merge pull request #9 from ngkaho1234/master
FIX: numerous bugs.
-rw-r--r--lwext4/ext4.c7
-rw-r--r--lwext4/ext4_xattr.c55
2 files changed, 32 insertions, 30 deletions
diff --git a/lwext4/ext4.c b/lwext4/ext4.c
index 6923b1b..e3c8154 100644
--- a/lwext4/ext4.c
+++ b/lwext4/ext4.c
@@ -2053,6 +2053,7 @@ static int ext4_iterate_ea_list(struct ext4_xattr_ref *ref,
if (prefix) {
memcpy(lxi->list_ptr, prefix, prefix_len);
lxi->list_ptr += prefix_len;
+ lxi->ret_size += prefix_len;
}
memcpy(lxi->list_ptr, item->name, item->name_len);
lxi->list_ptr[item->name_len] = 0;
@@ -2106,11 +2107,9 @@ int ext4_listxattr(const char *path, char *list, size_t size, size_t *ret_size)
r = ERANGE;
if (r == EOK) {
- if (lxi.get_required_size) {
- if (ret_size)
- *ret_size = lxi.ret_size;
+ if (ret_size)
+ *ret_size = lxi.ret_size;
- }
}
ext4_fs_put_xattr_ref(&xattr_ref);
ext4_fs_put_inode_ref(&inode_ref);
diff --git a/lwext4/ext4_xattr.c b/lwext4/ext4_xattr.c
index 9491e9a..e4e19fb 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)
@@ -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);