aboutsummaryrefslogtreecommitdiff
path: root/usr.sbin
diff options
context:
space:
mode:
authorAlan Somers <asomers@FreeBSD.org>2022-05-16 22:32:10 +0000
committerAlan Somers <asomers@FreeBSD.org>2022-05-16 22:32:10 +0000
commitecdc04d006de93eb343ce3b77208abd937d4f8ac (patch)
tree864fa322c99a9d3bc34dee1d7263dd28a754708b /usr.sbin
parentc1e0431c2202faa178642c8b54e545df3ed44f5f (diff)
downloadsrc-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.c50
-rwxr-xr-xusr.sbin/makefs/tests/makefs_ffs_tests.sh1
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 \