Allocate extra inodes in makefs when leaving free space in UFS images.

By default, makefs(8) has very few spare inodes in its output images,
which is fine for static filesystems, but not so great for VM images
where many more files will be added. Make makefs(8) use the same
default settings as newfs(8) when creating images with free space --
there isn't much point to leaving free space on the image if you
can't put files there. If no free space is requested, use current
behavior of a minimal number of available inodes.

Reviewed by:	manu
MFC after:	3 weeks
Differential Revision:	https://reviews.freebsd.org/D29492
This commit is contained in:
Nathan Whitehorn 2021-04-06 13:43:29 -04:00
parent 9e6158d274
commit afb6a168f8
4 changed files with 30 additions and 3 deletions

View File

@ -190,6 +190,7 @@ ffs_prep_opts(fsinfo_t *fsopts)
ffs_opts->fsize= -1;
ffs_opts->cpg= -1;
ffs_opts->density= -1;
ffs_opts->min_inodes= false;
ffs_opts->minfree= -1;
ffs_opts->optimization= -1;
ffs_opts->maxcontig= -1;
@ -266,6 +267,11 @@ ffs_makefs(const char *image, const char *dir, fsnode *root, fsinfo_t *fsopts)
printf("ffs_makefs: image %s directory %s root %p\n",
image, dir, root);
/* if user wants no free space, use minimum number of inodes */
if (fsopts->minsize == 0 && fsopts->freeblockpc == 0 &&
fsopts->freeblocks == 0)
((ffs_opt_t *)fsopts->fs_specific)->min_inodes = true;
/* validate tree and options */
TIMER_START(start);
ffs_validate(dir, root, fsopts);
@ -424,7 +430,7 @@ ffs_validate(const char *dir, fsnode *root, fsinfo_t *fsopts)
if (fsopts->roundup > 0)
fsopts->size = roundup(fsopts->size, fsopts->roundup);
/* calculate density if necessary */
/* calculate density to just fit inodes if no free space */
if (ffs_opts->density == -1)
ffs_opts->density = fsopts->size / fsopts->inodes + 1;

View File

@ -44,6 +44,7 @@
#include <ufs/ufs/dinode.h>
#include <ufs/ffs/fs.h>
#include <stdbool.h>
typedef struct {
char label[MAXVOLLEN]; /* volume name/label */
@ -52,6 +53,7 @@ typedef struct {
int cpg; /* cylinders per group */
int cpgflg; /* cpg was specified by user */
int density; /* bytes per inode */
bool min_inodes; /* allocate minimum number of inodes */
int ntracks; /* number of tracks */
int nsectors; /* number of sectors */
int rpm; /* rpm */

View File

@ -117,10 +117,13 @@ static int avgfpdir; /* expected number of files per directory */
struct fs *
ffs_mkfs(const char *fsys, const fsinfo_t *fsopts, time_t tstamp)
{
int fragsperinode, optimalfpg, origdensity, minfpg, lastminfpg;
int fragsperinode, optimalfpg, origdensity, mindensity;
int minfpg, lastminfpg;
int32_t csfrags;
uint32_t i, cylno;
long long sizepb;
ino_t maxinum;
int minfragsperinode; /* minimum ratio of frags to inodes */
void *space;
int size;
int nprintcols, printcolwidth;
@ -312,7 +315,20 @@ ffs_mkfs(const char *fsys, const fsinfo_t *fsopts, time_t tstamp)
* can put into each cylinder group. If this is too big, we reduce
* the density until it fits.
*/
maxinum = (((int64_t)(1)) << 32) - INOPB(&sblock);
minfragsperinode = 1 + fssize / maxinum;
mindensity = minfragsperinode * fsize;
if (density == 0)
density = MAX(2, minfragsperinode) * fsize;
if (density < mindensity) {
origdensity = density;
density = mindensity;
fprintf(stderr, "density increased from %d to %d\n",
origdensity, density);
}
origdensity = density;
if (!ffs_opts->min_inodes)
density = MIN(density, MAX(2, minfragsperinode) * fsize);
for (;;) {
fragsperinode = MAX(numfrags(&sblock, density), 1);
minfpg = fragsperinode * INOPB(&sblock);

View File

@ -312,7 +312,10 @@ Expected number of files per directory.
.It Sy bsize
Block size.
.It Sy density
Bytes per inode.
Bytes per inode. If unset, will allocate the minimum number of inodes to
represent the filesystem if no free space has been requested (free blocks
or minimum size set); otherwise the larger of the newfs defaults or what
is required by the free inode parameters if set.
.It Sy fsize
Fragment size.
.It Sy label