On Tue, Jan 05, 2010 at 01:29:19PM +0100, Otto Moerbeek wrote: > On Tue, Jan 05, 2010 at 06:18:53AM -0600, Marco Peereboom wrote: > > > You should make that mem patch available to reduce fsck surprises. > > yes, but I have to tweak it first. Currently it does not take into > account the (expected) number of dirs. It just takes ndirs, which is > pretty low for a new fs ;-)
Ok, here you go. This should give an reasonable estimate of the amount of memory needed to fsck a filesystem. This is a lower bound, actual memory use can get higher if you have lots of long file names, or lots of dirs, for example. With this diff newfs just prints the number. It's up to yourself to validate things. I have to think a bit how to incorporate this into newfs for real. -Otto Index: mkfs.c =================================================================== RCS file: /cvs/src/sbin/newfs/mkfs.c,v retrieving revision 1.72 diff -u -p -r1.72 mkfs.c --- mkfs.c 8 Aug 2008 23:49:53 -0000 1.72 +++ mkfs.c 5 Jan 2010 12:40:45 -0000 @@ -40,6 +40,7 @@ */ #include <sys/param.h> +#include <machine/vmparam.h> #include <sys/time.h> #include <sys/disklabel.h> #include <sys/ioctl.h> @@ -137,6 +138,7 @@ int isblock(struct fs *, unsigned char void rdfs(daddr64_t, int, void *); void mkfs(struct partition *, char *, int, int, mode_t, uid_t, gid_t); +static void checksz(void); #ifndef STANDALONE volatile sig_atomic_t cur_cylno; @@ -494,6 +496,7 @@ mkfs(struct partition *pp, char *fsys, i sblock.fs_fpg / sblock.fs_frag, sblock.fs_ipg); #undef B2MBFACTOR } + checksz(); /* * Wipe out old FFS1 superblock if necessary. @@ -1152,4 +1155,38 @@ ilog2(int val) return (n); errx(1, "ilog2: %d is not a power of 2\n", val); +} + +struct inoinfo { + struct inoinfo *i_nexthash; /* next entry in hash chain */ + struct inoinfo *i_child, *i_sibling, *i_parentp; + size_t i_isize; /* size of inode */ + ino_t i_number; /* inode number of this entry */ + ino_t i_parent; /* inode number of parent */ + + ino_t i_dotdot; /* inode number of `..' */ + u_int i_numblks; /* size of block array in bytes */ + daddr64_t i_blks[1]; /* actually longer */ +}; + +static void +checksz(void) +{ + unsigned long long allocate, maxino, maxfsblock, ndir; + + allocate = 0; + maxino = sblock.fs_ncg * (unsigned long long)sblock.fs_ipg; + maxfsblock = sblock.fs_size; + ndir = maxino / avgfilesperdir; + + allocate += roundup(howmany(maxfsblock, NBBY), sizeof(int16_t)); + allocate += (maxino + 1) * 3; + allocate += sblock.fs_ncg * sizeof(long); + allocate += (MAX(ndir, 128) + 10) * sizeof(struct inoinfo); + allocate += MAX(ndir, 128) * sizeof(struct inoinfo); + if (allocate > MAXDSIZ || 1) + warnx("fsck_ffs needs at least %lluM to fsck " + "this filesystem, MAXDSIZ is %lluM", + allocate / (1024ULL * 1024ULL), MAXDSIZ / + (1024ULL * 1024ULL)); }