Subject: Re: Repeatable mkdir ffs panic (affects both Free- and NetBSD)
To: None <current-users@netbsd.org, freebsd-hackers@freebsd.org>
From: BOUWSMA Beery <freebsd-misuser@dcf77-zeit.netscum.dyndns.dk>
List: current-users
Date: 05/27/2002 20:58:53
[This is sent both to the NetBSD list, plus FreeBSD, again, sorry]

Breaking all accepted rules of etiquette, I followup to meself:

I wrote...

> Fatal trap 18: integer divide fault while in kernel mode

> #5  0xc0201a7d in ffs_dirpref (pip=0xc14f1500)
>     at /usr/src/sys/ufs/ffs/ffs_alloc.c:710
> 710             maxcontigdirs = min(cgsize / dirsize, 255);

>         int cg, prefcg, dirsize, cgsize;
>         cgsize = fs->fs_fsize * fs->fs_fpg;
>         dirsize = fs->fs_avgfilesize * fs->fs_avgfpdir;

> the norm, would it be appropriate for me to waddle around in this
> section of code, to use 64-bit numbers where appropriate, or is


I'm happy to report that my hacks, changing the types of
cgsize (in my case 8192 * 439808) and dirsize (67108864 * 64),
as well as curdirsize for good measure, from the original signed
32 bit int to a 64-bit type, and then frobbing all references
following, resulted in a failure to panic my machine when `mkdir'ing
a subdirectory, at least under FreeBSD.

I'll see if I can do the same with NetBSD, but I suspect so.

Since I never learned any C, much less the proper way of doing
programming, I'd be happy to submit my hacks to someone who will
not laugh too much, but gently advise me on the proper way to do
what I tried to do, and who can merge them into the source tree
if appropriate, to avoid these kernel panics, assuming it's not
blindingly obvious how to do this right from my description.


Now to re-newfs that big drive with even larger numbers, and see
if I can induce panics elsewhere...


And concerning `newfs', I figured out what's going on, and I
suggest that FreeBSD imitate NetBSD here, and add the following
lines to newfs/mkfs.c for a second exit(19) case:
        if (sblock.fs_bsize > MAXBSIZE) {
                printf("block size %d is too large, maximum is %d\n",
                    sblock.fs_bsize, MAXBSIZE);
                exit(19);
        }
rather than letting memset() later overwrite zeros everywhere...


thanks
barry bouwsma