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.