diff options
author | Alan Somers <asomers@FreeBSD.org> | 2022-05-16 22:32:10 +0000 |
---|---|---|
committer | Alan Somers <asomers@FreeBSD.org> | 2022-05-16 22:32:10 +0000 |
commit | ecdc04d006de93eb343ce3b77208abd937d4f8ac (patch) | |
tree | 864fa322c99a9d3bc34dee1d7263dd28a754708b /usr.sbin | |
parent | c1e0431c2202faa178642c8b54e545df3ed44f5f (diff) | |
download | src-ecdc04d006de93eb343ce3b77208abd937d4f8ac.tar.gz src-ecdc04d006de93eb343ce3b77208abd937d4f8ac.zip |
makefs: fix calculation of file sizes
When a new FS image is created we need to calculate how much space each
file is going to consume.
Fix two bugs in that logic:
1) Count the space needed for indirect blocks for large files.
1) Normally the trailing data of a file is written to a block of frag
size, 4 kB by default.
However for files that use indirect blocks a full block is allocated,
32kB by default. Take that into account.
Adjust size calculations to match what is done in ffs_mkfs routine:
* Depending on the UFS version the superblock is stored at a different
offset. Take that into account.
* Add the cylinder group block size.
* All of the above has to be aligned to the block size.
Finally, Remove "ncg" variable. It's always 1 and it was used to
multiply stuff.
PR: 229929
Reviewed by: mckusick
MFC after: 2 weeks
Sponsored by: Semihalf
Submitted by: Kornel Dulęba <mindal@semihalf.com>
Differential Revision: https://reviews.freebsd.org/D35131
Differential Revision: https://reviews.freebsd.org/D35132
Diffstat (limited to 'usr.sbin')
-rw-r--r-- | usr.sbin/makefs/ffs.c | 50 | ||||
-rwxr-xr-x | usr.sbin/makefs/tests/makefs_ffs_tests.sh | 1 |
2 files changed, 30 insertions, 21 deletions
diff --git a/usr.sbin/makefs/ffs.c b/usr.sbin/makefs/ffs.c index 1e68b0931f16..81101b6aa6bf 100644 --- a/usr.sbin/makefs/ffs.c +++ b/usr.sbin/makefs/ffs.c @@ -324,7 +324,6 @@ ffs_makefs(const char *image, const char *dir, fsnode *root, fsinfo_t *fsopts) static void ffs_validate(const char *dir, fsnode *root, fsinfo_t *fsopts) { - int32_t ncg = 1; #ifdef notyet int32_t spc, nspf, ncyl, fssize; #endif @@ -395,22 +394,26 @@ ffs_validate(const char *dir, fsnode *root, fsinfo_t *fsopts) fsopts->size = fsopts->size * (100 + fsopts->freeblockpc) / 100; - /* add space needed for superblocks */ /* - * The old SBOFF (SBLOCK_UFS1) is used here because makefs is - * typically used for small filesystems where space matters. - * XXX make this an option. + * Add space needed for superblock, cylblock and to store inodes. + * All of those segments are aligned to the block size. + * XXX: This has to match calculations done in ffs_mkfs. */ - fsopts->size += (SBLOCK_UFS1 + SBLOCKSIZE) * ncg; - /* add space needed to store inodes, x3 for blockmaps, etc */ - if (ffs_opts->version == 1) - fsopts->size += ncg * DINODE1_SIZE * - roundup(fsopts->inodes / ncg, - ffs_opts->bsize / DINODE1_SIZE); - else - fsopts->size += ncg * DINODE2_SIZE * - roundup(fsopts->inodes / ncg, - ffs_opts->bsize / DINODE2_SIZE); + if (ffs_opts->version == 1) { + fsopts->size += + roundup(SBLOCK_UFS1 + SBLOCKSIZE, ffs_opts->bsize); + fsopts->size += roundup(SBLOCKSIZE, ffs_opts->bsize); + fsopts->size += ffs_opts->bsize; + fsopts->size += DINODE1_SIZE * + roundup(fsopts->inodes, ffs_opts->bsize / DINODE1_SIZE); + } else { + fsopts->size += + roundup(SBLOCK_UFS2 + SBLOCKSIZE, ffs_opts->bsize); + fsopts->size += roundup(SBLOCKSIZE, ffs_opts->bsize); + fsopts->size += ffs_opts->bsize; + fsopts->size += DINODE2_SIZE * + roundup(fsopts->inodes, ffs_opts->bsize / DINODE2_SIZE); + } /* add minfree */ if (ffs_opts->minfree > 0) @@ -620,12 +623,19 @@ ffs_size_dir(fsnode *root, fsinfo_t *fsopts) e, tmpdir.d_namlen, this, curdirsize); \ } while (0); - /* - * XXX this needs to take into account extra space consumed - * by indirect blocks, etc. - */ #define ADDSIZE(x) do { \ - fsopts->size += roundup((x), ffs_opts->fsize); \ + if ((size_t)(x) < UFS_NDADDR * (size_t)ffs_opts->bsize) { \ + fsopts->size += roundup((x), ffs_opts->fsize); \ + } else { \ + /* Count space consumed by indirecttion blocks. */ \ + fsopts->size += ffs_opts->bsize * \ + (howmany((x), UFS_NDADDR * ffs_opts->bsize) - 1); \ + /* \ + * If the file is big enough to use indirect blocks, \ + * we allocate bsize block for trailing data. \ + */ \ + fsopts->size += roundup((x), ffs_opts->bsize); \ + } \ } while (0); curdirsize = 0; diff --git a/usr.sbin/makefs/tests/makefs_ffs_tests.sh b/usr.sbin/makefs/tests/makefs_ffs_tests.sh index 55be19f099eb..1a415cb5f518 100755 --- a/usr.sbin/makefs/tests/makefs_ffs_tests.sh +++ b/usr.sbin/makefs/tests/makefs_ffs_tests.sh @@ -57,7 +57,6 @@ check_ffs_image_contents() atf_test_case autocalculate_image_size cleanup autocalculate_image_size_body() { - atf_expect_fail "PR 229929 makefs(8) can underestimate image size" create_test_inputs atf_check -e empty -o save:$TEST_SPEC_FILE -s exit:0 \ |