xref: /aosp_15_r20/external/e2fsprogs/contrib/dir2fs (revision 6a54128f25917bfc36a8a6e9d722c04a0b4641b6)
1*6a54128fSAndroid Build Coastguard Worker#!/bin/sh
2*6a54128fSAndroid Build Coastguard Worker
3*6a54128fSAndroid Build Coastguard Workerdir="$1"
4*6a54128fSAndroid Build Coastguard Workerdev="$2"
5*6a54128fSAndroid Build Coastguard Worker
6*6a54128fSAndroid Build Coastguard Workerif [ "$1" = "--help" ] || [ ! -d "${dir}" ]; then
7*6a54128fSAndroid Build Coastguard Worker	echo "Usage: $0 dir [mke2fs args] dev"
8*6a54128fSAndroid Build Coastguard Worker	exit 1
9*6a54128fSAndroid Build Coastguard Workerfi
10*6a54128fSAndroid Build Coastguard Worker
11*6a54128fSAndroid Build Coastguard Workershift
12*6a54128fSAndroid Build Coastguard Worker
13*6a54128fSAndroid Build Coastguard Worker# Goal: Put all the files at the beginning (which mke2fs does) and minimize
14*6a54128fSAndroid Build Coastguard Worker# the number of free inodes given the minimum number of blocks required.
15*6a54128fSAndroid Build Coastguard Worker# Hence all this math to get the inode ratio just right.
16*6a54128fSAndroid Build Coastguard Worker
17*6a54128fSAndroid Build Coastguard Workerbytes="$(du -ks "${dir}" | awk '{print $1}')"
18*6a54128fSAndroid Build Coastguard Workerbytes="$((bytes * 1024))"
19*6a54128fSAndroid Build Coastguard Workerinodes="$(find "${dir}" -print0 | xargs -0 stat -c '%i' | sort -g | uniq | wc -l)"
20*6a54128fSAndroid Build Coastguard Workerblock_sz=4096
21*6a54128fSAndroid Build Coastguard Workerinode_sz=256
22*6a54128fSAndroid Build Coastguard Workersb_overhead=4096
23*6a54128fSAndroid Build Coastguard Workerblocks_per_group="$((block_sz * 8))"
24*6a54128fSAndroid Build Coastguard Workerbytes_per_group="$((blocks_per_group * block_sz))"
25*6a54128fSAndroid Build Coastguard Workerinode_bytes="$((inodes * inode_sz))"
26*6a54128fSAndroid Build Coastguard Worker
27*6a54128fSAndroid Build Coastguard Worker# Estimate overhead with the minimum number of groups...
28*6a54128fSAndroid Build Coastguard Workernr_groups="$(( (bytes + inode_bytes + bytes_per_group - 1) / bytes_per_group))"
29*6a54128fSAndroid Build Coastguard Workerinode_bytes_per_group="$((inode_bytes / nr_groups))"
30*6a54128fSAndroid Build Coastguard Workerinode_blocks_per_group="$(( (inode_bytes_per_group + (block_sz - 1)) / block_sz ))"
31*6a54128fSAndroid Build Coastguard Workerper_grp_overhead="$(( ((3 + inode_blocks_per_group) * block_sz) + 64 ))"
32*6a54128fSAndroid Build Coastguard Workeroverhead="$(( sb_overhead + (per_grp_overhead * nr_groups) ))"
33*6a54128fSAndroid Build Coastguard Workerused_bytes="$((bytes + overhead))"
34*6a54128fSAndroid Build Coastguard Worker
35*6a54128fSAndroid Build Coastguard Worker# Then do it again with the real number of groups.
36*6a54128fSAndroid Build Coastguard Workernr_groups="$(( (used_bytes + (bytes_per_group - 1)) / bytes_per_group))"
37*6a54128fSAndroid Build Coastguard Workertot_blocks="$((nr_groups * blocks_per_group))"
38*6a54128fSAndroid Build Coastguard Workertot_bytes="$((tot_blocks * block_sz))"
39*6a54128fSAndroid Build Coastguard Worker
40*6a54128fSAndroid Build Coastguard Workerratio="$((bytes / inodes))"
41*6a54128fSAndroid Build Coastguard Workermkfs_blocks="$((tot_blocks * 4 / 3))"
42*6a54128fSAndroid Build Coastguard Worker
43*6a54128fSAndroid Build Coastguard Workermke2fs -i "${ratio}" -T ext4 -d "${dir}" -O ^resize_inode,sparse_super2,metadata_csum,64bit,^has_journal -E packed_meta_blocks=1,num_backup_sb=0 -b "${block_sz}" -I "${inodesz}" -F "${dev}" "${mkfs_blocks}" || exit
44*6a54128fSAndroid Build Coastguard Worker
45*6a54128fSAndroid Build Coastguard Workere2fsck -fyD "${dev}"
46*6a54128fSAndroid Build Coastguard Worker
47*6a54128fSAndroid Build Coastguard Workerblocks="$(dumpe2fs -h "${dev}" 2>&1 | grep 'Block count:' | awk '{print $3}')"
48*6a54128fSAndroid Build Coastguard Workerwhile resize2fs -f -M "${dev}"; do
49*6a54128fSAndroid Build Coastguard Worker	new_blocks="$(dumpe2fs -h "${dev}" 2>&1 | grep 'Block count:' | awk '{print $3}')"
50*6a54128fSAndroid Build Coastguard Worker	if [ "${new_blocks}" -eq "${blocks}" ]; then
51*6a54128fSAndroid Build Coastguard Worker		break;
52*6a54128fSAndroid Build Coastguard Worker	fi
53*6a54128fSAndroid Build Coastguard Worker	blocks="${new_blocks}"
54*6a54128fSAndroid Build Coastguard Workerdone
55*6a54128fSAndroid Build Coastguard Worker
56*6a54128fSAndroid Build Coastguard Workerif [ ! -b "${dev}" ]; then
57*6a54128fSAndroid Build Coastguard Worker    truncate -s "$((blocks * block_sz))" "${dev}" || (e2image -ar "${dev}" "${dev}.min"; mv "${dev}.min" "${dev}")
58*6a54128fSAndroid Build Coastguard Workerfi
59*6a54128fSAndroid Build Coastguard Worker
60*6a54128fSAndroid Build Coastguard Workere2fsck -fy "${dev}"
61*6a54128fSAndroid Build Coastguard Worker
62*6a54128fSAndroid Build Coastguard Workerdir_blocks="$((bytes / block_sz))"
63*6a54128fSAndroid Build Coastguard Workeroverhead="$((blocks - dir_blocks))"
64*6a54128fSAndroid Build Coastguard Workerecho "Minimized image overhead: $((100 * overhead / dir_blocks))%"
65*6a54128fSAndroid Build Coastguard Worker
66*6a54128fSAndroid Build Coastguard Workerexit 0
67