Don't sparse right-sized ext4 and erofs images.
When we introduced Dynamic Partitions, we stopped giving readonly
partitions fixed sizes. In addition we introduced deduplication for
ext4. These two factors greatly reduce the impact of sparse images,
since there aren't many fill blocks to optimize.
This patch disables sparsing for images that are rightsized and do not
explicitly specify extra reserved space. This makes the images a little
easier to work with from an engineering perspective. They no longer have
to be unsparsed to interact with any tooling. It also eases a potential
source of bugs, as b/184225422 is not reproducible with sparsing off.
On Pixel, the difference between the sparsed partitions and unsparsed is
12M (out of roughly 4G).
Bug: 198001223
Test: make, treehugger, make target-files-package
dynamic partitions are no longer sparse images
Change-Id: I74459f8abe74a15a24ba5a40cf701e6af2db8179
diff --git a/tools/releasetools/build_image.py b/tools/releasetools/build_image.py
index f2ba321..189da37 100755
--- a/tools/releasetools/build_image.py
+++ b/tools/releasetools/build_image.py
@@ -256,9 +256,11 @@
needs_casefold = prop_dict.get("needs_casefold", 0)
needs_compress = prop_dict.get("needs_compress", 0)
+ disable_sparse = "disable_sparse" in prop_dict
+
if fs_type.startswith("ext"):
build_command = [prop_dict["ext_mkuserimg"]]
- if "extfs_sparse_flag" in prop_dict:
+ if "extfs_sparse_flag" in prop_dict and not disable_sparse:
build_command.append(prop_dict["extfs_sparse_flag"])
run_e2fsck = True
build_command.extend([in_dir, out_file, fs_type,
@@ -303,7 +305,7 @@
elif fs_type.startswith("erofs"):
build_command = ["mkerofsimage.sh"]
build_command.extend([in_dir, out_file])
- if "erofs_sparse_flag" in prop_dict:
+ if "erofs_sparse_flag" in prop_dict and not disable_sparse:
build_command.extend([prop_dict["erofs_sparse_flag"]])
build_command.extend(["-m", prop_dict["mount_point"]])
if target_out:
@@ -319,7 +321,7 @@
elif fs_type.startswith("squash"):
build_command = ["mksquashfsimage.sh"]
build_command.extend([in_dir, out_file])
- if "squashfs_sparse_flag" in prop_dict:
+ if "squashfs_sparse_flag" in prop_dict and not disable_sparse:
build_command.extend([prop_dict["squashfs_sparse_flag"]])
build_command.extend(["-m", prop_dict["mount_point"]])
if target_out:
@@ -341,7 +343,7 @@
elif fs_type.startswith("f2fs"):
build_command = ["mkf2fsuserimg.sh"]
build_command.extend([out_file, prop_dict["image_size"]])
- if "f2fs_sparse_flag" in prop_dict:
+ if "f2fs_sparse_flag" in prop_dict and not disable_sparse:
build_command.extend([prop_dict["f2fs_sparse_flag"]])
if fs_config:
build_command.extend(["-C", fs_config])
@@ -448,6 +450,8 @@
# or None if not applicable.
verity_image_builder = verity_utils.CreateVerityImageBuilder(prop_dict)
+ disable_sparse = "disable_sparse" in prop_dict
+
if (prop_dict.get("use_dynamic_partition_size") == "true" and
"partition_size" not in prop_dict):
# If partition_size is not defined, use output of `du' + reserved_size.
@@ -481,7 +485,7 @@
size // BYTES_IN_MB, prop_dict["extfs_inode_count"])
BuildImageMkfs(in_dir, prop_dict, out_file, target_out, fs_config)
sparse_image = False
- if "extfs_sparse_flag" in prop_dict:
+ if "extfs_sparse_flag" in prop_dict and not disable_sparse:
sparse_image = True
fs_dict = GetFilesystemCharacteristics(fs_type, out_file, sparse_image)
os.remove(out_file)
@@ -525,7 +529,7 @@
prop_dict["image_size"] = str(size)
BuildImageMkfs(in_dir, prop_dict, out_file, target_out, fs_config)
sparse_image = False
- if "f2fs_sparse_flag" in prop_dict:
+ if "f2fs_sparse_flag" in prop_dict and not disable_sparse:
sparse_image = True
fs_dict = GetFilesystemCharacteristics(fs_type, out_file, sparse_image)
os.remove(out_file)
@@ -642,6 +646,7 @@
d["extfs_rsv_pct"] = "0"
copy_prop("system_reserved_size", "partition_reserved_size")
copy_prop("system_selinux_fc", "selinux_fc")
+ copy_prop("system_disable_sparse", "disable_sparse")
elif mount_point == "system_other":
# We inherit the selinux policies of /system since we contain some of its
# files.
@@ -668,6 +673,7 @@
d["extfs_rsv_pct"] = "0"
copy_prop("system_reserved_size", "partition_reserved_size")
copy_prop("system_selinux_fc", "selinux_fc")
+ copy_prop("system_disable_sparse", "disable_sparse")
elif mount_point == "data":
# Copy the generic fs type first, override with specific one if available.
copy_prop("fs_type", "fs_type")
@@ -708,6 +714,7 @@
d["extfs_rsv_pct"] = "0"
copy_prop("vendor_reserved_size", "partition_reserved_size")
copy_prop("vendor_selinux_fc", "selinux_fc")
+ copy_prop("vendor_disable_sparse", "disable_sparse")
elif mount_point == "product":
copy_prop("avb_product_hashtree_enable", "avb_hashtree_enable")
copy_prop("avb_product_add_hashtree_footer_args",
@@ -733,6 +740,7 @@
d["extfs_rsv_pct"] = "0"
copy_prop("product_reserved_size", "partition_reserved_size")
copy_prop("product_selinux_fc", "selinux_fc")
+ copy_prop("product_disable_sparse", "disable_sparse")
elif mount_point == "system_ext":
copy_prop("avb_system_ext_hashtree_enable", "avb_hashtree_enable")
copy_prop("avb_system_ext_add_hashtree_footer_args",
@@ -760,6 +768,7 @@
d["extfs_rsv_pct"] = "0"
copy_prop("system_ext_reserved_size", "partition_reserved_size")
copy_prop("system_ext_selinux_fc", "selinux_fc")
+ copy_prop("system_ext_disable_sparse", "disable_sparse")
elif mount_point == "odm":
copy_prop("avb_odm_hashtree_enable", "avb_hashtree_enable")
copy_prop("avb_odm_add_hashtree_footer_args",
@@ -783,6 +792,7 @@
d["extfs_rsv_pct"] = "0"
copy_prop("odm_reserved_size", "partition_reserved_size")
copy_prop("odm_selinux_fc", "selinux_fc")
+ copy_prop("odm_disable_sparse", "disable_sparse")
elif mount_point == "vendor_dlkm":
copy_prop("avb_vendor_dlkm_hashtree_enable", "avb_hashtree_enable")
copy_prop("avb_vendor_dlkm_add_hashtree_footer_args",
@@ -808,6 +818,7 @@
d["extfs_rsv_pct"] = "0"
copy_prop("vendor_dlkm_reserved_size", "partition_reserved_size")
copy_prop("vendor_dlkm_selinux_fc", "selinux_fc")
+ copy_prop("vendor_dlkm_disable_sparse", "disable_sparse")
elif mount_point == "odm_dlkm":
copy_prop("avb_odm_dlkm_hashtree_enable", "avb_hashtree_enable")
copy_prop("avb_odm_dlkm_add_hashtree_footer_args",
@@ -831,6 +842,7 @@
d["extfs_rsv_pct"] = "0"
copy_prop("odm_dlkm_reserved_size", "partition_reserved_size")
copy_prop("odm_dlkm_selinux_fc", "selinux_fc")
+ copy_prop("odm_dlkm_disable_sparse", "disable_sparse")
elif mount_point == "oem":
copy_prop("fs_type", "fs_type")
copy_prop("oem_size", "partition_size")