Add support for sparse ext4 image creation.
This adds the -s option to the make_ext4fs tool, which now creates
"sparse" filesystem images, which is very useful for the large 32 Gbyte
filesystems we are now building.
This check-in also fixes make_ext4fs to properly create filesystems
larger thatn 4 Gbytes on 64-bit Linux, 32-bit android and Macs.
Change-Id: Ie5838492fcf944f5c875481693c0dbd7013deae4
diff --git a/ext4_utils/ext4_utils.c b/ext4_utils/ext4_utils.c
index cd82827..f34985f 100644
--- a/ext4_utils/ext4_utils.c
+++ b/ext4_utils/ext4_utils.c
@@ -14,6 +14,19 @@
* limitations under the License.
*/
+#include <fcntl.h>
+#include <arpa/inet.h>
+#include <sys/ioctl.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <string.h>
+
+#if defined(__linux__)
+#include <linux/fs.h>
+#elif defined(__APPLE__) && defined(__MACH__)
+#include <sys/disk.h>
+#endif
+
#include "ext4_utils.h"
#include "output_file.h"
#include "backed_block.h"
@@ -25,18 +38,6 @@
#include "ext4.h"
#include "jbd2.h"
-#include <fcntl.h>
-#include <arpa/inet.h>
-#include <sys/ioctl.h>
-#include <sys/stat.h>
-#include <sys/types.h>
-
-#if defined(__linux__)
-#include <linux/fs.h>
-#elif defined(__APPLE__) && defined(__MACH__)
-#include <sys/disk.h>
-#endif
-
int force = 0;
struct fs_info info;
struct fs_aux_info aux_info;
@@ -73,24 +74,36 @@
}
/* Write the filesystem image to a file */
-void write_ext4_image(const char *filename, int gz)
+void write_ext4_image(const char *filename, int gz, int sparse)
{
int ret = 0;
- struct output_file *out = open_output_file(filename, gz);
+ struct output_file *out = open_output_file(filename, gz, sparse);
off_t off;
if (!out)
return;
- write_data_block(out, 1024, (u8*)aux_info.sb, 1024);
+ /* The write_data* functions expect only block aligned calls.
+ * This is not an issue, except when we write out the super
+ * block on a system with a block size > 1K. So, we need to
+ * deal with that here.
+ */
+ if (info.block_size > 1024) {
+ u8 buf[4096] = { 0 }; /* The larget supported ext4 block size */
+ memcpy(buf + 1024, (u8*)aux_info.sb, 1024);
+ write_data_block(out, 0, buf, info.block_size);
- write_data_block(out, (aux_info.first_data_block + 1) * info.block_size,
+ } else {
+ write_data_block(out, 1024, (u8*)aux_info.sb, 1024);
+ }
+
+ write_data_block(out, (u64)(aux_info.first_data_block + 1) * info.block_size,
(u8*)aux_info.bg_desc,
aux_info.bg_desc_blocks * info.block_size);
for_each_data_block(write_data_block, write_data_file, out);
- write_data_block(out, info.len - 1, (u8*)"", 1);
+ pad_output_file(out, info.len);
close_output_file(out);
}