Fix calculation of dentry size

The PAD_TO function was incorrectly handling values that were already
aligned, which could lead to overruns of the dentry block.  Fix the
function, rename it to ALIGN, move it to ext4_utils.h, and use it
everywhere the dentry size is calculated.

Change-Id: Ie9778d2c6f72d3db9a3162e52882377a71b8420a
diff --git a/ext4_utils/contents.c b/ext4_utils/contents.c
index 9fcd3b3..0ecdfd4 100644
--- a/ext4_utils/contents.c
+++ b/ext4_utils/contents.c
@@ -30,10 +30,10 @@
 {
 	u32 len = 24;
 	unsigned int i;
+	unsigned int dentry_len;
 
 	for (i = 0; i < entries; i++) {
-		unsigned int dentry_len = 8 + 4 *
-			DIV_ROUND_UP(strlen(dentries[i].filename), 4);
+		dentry_len = 8 + ALIGN(strlen(dentries[i].filename), 4);
 		if (len % info.block_size + dentry_len > info.block_size)
 			len += info.block_size - (len % info.block_size);
 		len += dentry_len;
@@ -42,14 +42,12 @@
 	return len;
 }
 
-#define PAD_TO(x, y) (x + (y - (x % y)))
-
 static struct ext4_dir_entry_2 *add_dentry(u8 *data, u32 *offset,
 		struct ext4_dir_entry_2 *prev, u32 inode, const char *name,
 		u8 file_type)
 {
 	u8 name_len = strlen(name);
-	u16 rec_len = 8 + PAD_TO(name_len, 4);
+	u16 rec_len = 8 + ALIGN(name_len, 4);
 	struct ext4_dir_entry_2 *dentry;
 
 	u32 start_block = *offset / info.block_size;
@@ -84,14 +82,17 @@
 	u32 dirs)
 {
 	struct ext4_inode *inode;
-	u32 blocks = DIV_ROUND_UP(dentry_size(entries, dentries), info.block_size);
-	u64 len = (u64)blocks * info.block_size;
+	u32 blocks;
+	u32 len;
 	u32 offset = 0;
 	u32 inode_num;
 	u8 *data;
 	unsigned int i;
 	struct ext4_dir_entry_2 *dentry;
 
+	blocks = DIV_ROUND_UP(dentry_size(entries, dentries), info.block_size);
+	len = blocks * info.block_size;
+
 	if (dir_inode_num) {
 		inode_num = allocate_inode(info);
 	} else {
@@ -137,8 +138,11 @@
 	}
 
 	for (i = 0; i < entries; i++) {
-		dentry = add_dentry(data, &offset, dentry, 0, dentries[i].filename,
-				dentries[i].file_type);
+		dentry = add_dentry(data, &offset, dentry, 0,
+				dentries[i].filename, dentries[i].file_type);
+		if (offset > len || (offset == len && i != entries - 1))
+			critical_error("internal error: dentry for %s ends at %d, past %d\n",
+				dentries[i].filename, offset, len);
 		dentries[i].inode = &dentry->inode;
 		if (!dentry) {
 			error("failed to add directory");
diff --git a/ext4_utils/ext4_utils.h b/ext4_utils/ext4_utils.h
index 294c8c5..0a2b542 100644
--- a/ext4_utils/ext4_utils.h
+++ b/ext4_utils/ext4_utils.h
@@ -38,6 +38,7 @@
 #define min(a, b) ((a) < (b) ? (a) : (b))
 
 #define DIV_ROUND_UP(x, y) (((x) + (y) - 1)/(y))
+#define ALIGN(x, y) ((y) * DIV_ROUND_UP((x), (y)))
 
 #define __le64 u64
 #define __le32 u32