The branch main has been updated by asomers:

URL: 
https://cgit.FreeBSD.org/src/commit/?id=ecdc04d006de93eb343ce3b77208abd937d4f8ac

commit ecdc04d006de93eb343ce3b77208abd937d4f8ac
Author:     Alan Somers <[email protected]>
AuthorDate: 2022-05-16 22:32:10 +0000
Commit:     Alan Somers <[email protected]>
CommitDate: 2022-05-16 22:32:10 +0000

    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 <[email protected]>
    Differential Revision:  https://reviews.freebsd.org/D35131
    Differential Revision:  https://reviews.freebsd.org/D35132
---
 usr.sbin/makefs/ffs.c                     | 50 ++++++++++++++++++-------------
 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 \

Reply via email to