shithub: lwext4

Download patch

ref: 59950cfeb06442b20ccebf9f0c94d5f35370ae15
parent: 9792c01efcf868269bab6cce4fa6efefcc1adcb6
parent: a4ec81fd03739007d083a7cc3bfaf5e548cefc8e
author: gkostka <[email protected]>
date: Sat Oct 10 00:29:21 EDT 2015

Merge pull request #9 from ngkaho1234/master

FIX: numerous bugs.

--- a/lwext4/ext4.c
+++ b/lwext4/ext4.c
@@ -2053,6 +2053,7 @@
 		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 @@
 		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);
--- a/lwext4/ext4_xattr.c
+++ b/lwext4/ext4_xattr.c
@@ -371,11 +371,18 @@
 	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 @@
 			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 @@
 				  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 @@
 	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,8 +454,6 @@
 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);
@@ -444,12 +460,6 @@
 		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 @@
 					&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 @@
 	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 @@
 		if (rc != EOK)
 			return EIO;
 
-		ref->ea_size += sizeof(struct ext4_xattr_header);
 		ref->block_loaded = true;
 	} else
 		ref->block_loaded = false;
@@ -769,10 +776,6 @@
 
 	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) {