shithub: lwext4

Download patch

ref: d28be3a3f0252e2620f761119abcf0d4383ee5b3
parent: aff43c4a6a0c8ea6cc1d19d53b0b083a89c7707f
author: ngkaho1234 <[email protected]>
date: Sun Oct 11 11:06:23 EDT 2015

FIX: cannot delete files containing unwritten extent properly.
TODO: we also need to add the support of writting to a file containing unwritten extent.

--- a/lwext4/ext4_extent.c
+++ b/lwext4/ext4_extent.c
@@ -61,12 +61,18 @@
 
 uint16_t ext4_extent_get_block_count(struct ext4_extent *extent)
 {
-	return to_le16(extent->block_count);
+	if (EXT4_EXT_IS_UNWRITTEN(extent))
+		return EXT4_EXT_GET_LEN_UNWRITTEN(extent);
+	else
+		return EXT4_EXT_GET_LEN(extent);
 }
 
-void ext4_extent_set_block_count(struct ext4_extent *extent, uint16_t count)
+void ext4_extent_set_block_count(struct ext4_extent *extent, uint16_t count,
+				 bool unwritten)
 {
-	extent->block_count = to_le16(count);
+	EXT4_EXT_SET_LEN(extent, count);
+	if (unwritten)
+		EXT4_EXT_SET_UNWRITTEN(extent);
 }
 
 uint64_t ext4_extent_get_start(struct ext4_extent *extent)
@@ -493,7 +499,8 @@
 
 	/* Correct counter */
 	block_count -= delete_count;
-	ext4_extent_set_block_count(path_ptr->extent, block_count);
+	ext4_extent_set_block_count(path_ptr->extent, block_count,
+				EXT4_EXT_IS_UNWRITTEN(path_ptr->extent));
 
 	/* Initialize the following loop */
 	uint16_t entries =
@@ -873,7 +880,8 @@
 			ext4_extent_set_first_block(path_ptr->extent,
 						    new_block_idx);
 			ext4_extent_set_start(path_ptr->extent, phys_block);
-			ext4_extent_set_block_count(path_ptr->extent, 1);
+			ext4_extent_set_block_count(path_ptr->extent, 1,
+						false);
 
 			/* Update i-node */
 			if (update_size) {
@@ -908,7 +916,8 @@
 
 			/* Update extent */
 			ext4_extent_set_block_count(path_ptr->extent,
-						    block_count + 1);
+						    block_count + 1,
+						    false);
 
 			/* Update i-node */
 			if (update_size) {
@@ -943,7 +952,7 @@
 	path_ptr = path + tree_depth;
 
 	/* Initialize newly created extent */
-	ext4_extent_set_block_count(path_ptr->extent, 1);
+	ext4_extent_set_block_count(path_ptr->extent, 1, false);
 	ext4_extent_set_first_block(path_ptr->extent, new_block_idx);
 	ext4_extent_set_start(path_ptr->extent, phys_block);
 
--- a/lwext4/ext4_extent.h
+++ b/lwext4/ext4_extent.h
@@ -61,8 +61,10 @@
 
 /**@brief Set number of blocks covered by extent.
  * @param extent Extent to load count from
- * @param count  Number of blocks covered by extent */
-void ext4_extent_set_block_count(struct ext4_extent *extent, uint16_t count);
+ * @param count  Number of blocks covered by extent
+ * @param unwritten Whether the extent is unwritten or not */
+void ext4_extent_set_block_count(struct ext4_extent *extent, uint16_t count,
+				 bool unwritten);
 
 /**@brief Get physical number of the first block covered by extent.
  * @param extent Extent to load number
--- a/lwext4/ext4_types.h
+++ b/lwext4/ext4_types.h
@@ -555,6 +555,25 @@
 
 #define EXT4_LINK_MAX 65000
 
+#define EXT4_EXT_UNWRITTEN_MASK (1 << 15)
+
+#define EXT4_EXT_MAX_LEN_WRITTEN (1 << 15)
+#define EXT4_EXT_MAX_LEN_UNWRITTEN \
+	(EXT4_EXT_MAX_LEN_WRITTEN - 1)
+
+#define EXT4_EXT_GET_LEN(ex) to_le16((ex)->block_count)
+#define EXT4_EXT_GET_LEN_UNWRITTEN(ex) \
+	(EXT4_EXT_GET_LEN(ex) &= ~(EXT4_EXT_UNWRITTEN_MASK))
+#define EXT4_EXT_SET_LEN(ex, count) \
+	((ex)->block_count = to_le16(count))
+
+#define EXT4_EXT_IS_UNWRITTEN(ex) \
+	(EXT4_EXT_GET_LEN(ex) > EXT4_EXT_MAX_LEN_WRITTEN)
+#define EXT4_EXT_SET_UNWRITTEN(ex) \
+	((ex)->block_count |= to_le16(EXT4_EXT_UNWRITTEN_MASK))
+#define EXT4_EXT_SET_WRITTEN(ex) \
+	((ex)->block_count &= ~(to_le16(EXT4_EXT_UNWRITTEN_MASK)))
+
 /*
  * This is the extent on-disk structure.
  * It's used at the bottom of the tree.