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));
 }

Reply via email to