Skip site navigation (1)Skip section navigation (2)
Date:      Thu, 31 Oct 2002 14:30:59 -0800 (PST)
From:      David Wolfskill <david@catwhisker.org>
To:        current@freebsd.org
Cc:        mckusick@freebsd.org
Subject:   newfs chokes, cores, & dies if inode density too high; patch attached
Message-ID:  <200210312230.g9VMUxni040707@bunrab.catwhisker.org>

next in thread | raw e-mail | index | archive | help
For various reasons (most of which are likely historical), I tend
to mount /tmp as a swap-backed memory file system (and allocate
quite a bit of space to swap).  Thus, in -STABLE, I use an mfs; in
-CURRENT, I use a little shell script (cribbed almost verbatim from
"man mdconfig").

Some months back, my (daily) "make buildworld" failed, and I
determined that the reason was that I had exhausted the inode supply
in /tmp.

OK; I figured I could address that by overriding some defaults when
I did the newfs, such as specifying -i to provide a "density" override.
(The only flag I had been using on newfs was "-U", so soft updates would
be enabled.)

Now, I had made the file system 512 MB in size, and (as noted above)
left defaults in for everything else.  Given that, the effective value
that was being used for density was 8192.  (Unit of measure here is
"number of bytes per inode," so a smaller "density" yields more inodes.)

So I dropped the density to 2048, and things were generally OK (in this
respect, anyway) until about a month or so ago.  Then newfs started
dumping core.  (Since I had enough space on the root file system, this
just prevented the swap-backed /tmp from being mounted.)

Today, I finally decided to find out what was causing this.

Turns out that the newfs mainline calls mkfs() (which is in mkfs.c --
all of the referenced source files are in src/sbin/newfs).  And it was
mkfs() that was choking; in particular, on line 308 of

  "$FreeBSD: src/sbin/newfs/mkfs.c,v 1.63 2002/10/18 23:17:30 mckusick Exp $";

		sblock.fs_ipg = roundup(howmany(sblock.fs_fpg, fragsperinode),
		    INOPB(&sblock));

"howmany()" is actually a macro (from sys/param.h -- as is roundup()),
and it divides by fragsperinode, which (if density is <4096) is set to 0
at line 299:

		fragsperinode = numfrags(&sblock, density);

OK; I recall that dividing by 0 is Generally Bad.  On the other hand,
this seemed to be a less-than-graceful way to deal with the issue.  But
I wasn't willing (at this time) to try figuring out just what the Right
Thing To Do would be, and settled on:

Index: mkfs.c
===================================================================
RCS file: /cvs/freebsd/src/sbin/newfs/mkfs.c,v
retrieving revision 1.63
diff -u -r1.63 mkfs.c
--- mkfs.c	18 Oct 2002 23:17:30 -0000	1.63
+++ mkfs.c	31 Oct 2002 21:22:41 -0000
@@ -297,6 +297,8 @@
 	origdensity = density;
 	for (;;) {
 		fragsperinode = numfrags(&sblock, density);
+		if (fragsperinode < 1)
+			fragsperinode = 1;
 		minfpg = fragsperinode * INOPB(&sblock);
 		if (minfpg > sblock.fs_size)
 			minfpg = sblock.fs_size;


So this is pretty much a Gross Hack; its sole redeeming virtue is
that it prevents newfs from dying under these conditions.  Indeed,
it causes it to (silently) behave as if "-i 4096" had been specified:

freebeast(5.0-C)[32] sudo /usr/obj/usr/src/sbin/newfs/newfs -U -i 2048 /dev/md10
/dev/md10: 512.0MB (1048576 sectors) block size 16384, fragment size 4096
        using 4 cylinder groups of 128.02MB, 8193 blks, 32896 inodes.
        with soft updates
super-block backups (for fsck -b #) at:
 32, 262208, 524384, 786560
freebeast(5.0-C)[33] sudo df -i !$
sudo df -i /dev/md10
Filesystem  1K-blocks     Used    Avail Capacity iused   ifree %iused  Mounted on
/dev/md10      507692        4   467076     0%       1  131581    0%   
freebeast(5.0-C)[34] sudo /usr/obj/usr/src/sbin/newfs/newfs -U -i 4096 /dev/md10 
/dev/md10: 512.0MB (1048576 sectors) block size 16384, fragment size 4096
        using 4 cylinder groups of 128.02MB, 8193 blks, 32896 inodes.
        with soft updates
super-block backups (for fsck -b #) at:
 32, 262208, 524384, 786560
freebeast(5.0-C)[35] sudo df -i /dev/md10
Filesystem  1K-blocks     Used    Avail Capacity iused   ifree %iused  Mounted on
/dev/md10      507692        4   467076     0%       1  131581    0%   
freebeast(5.0-C)[36]


So I won't claim that the patch is in any sense optimal, but it seems
to me that it's somewhat of an improvement.  Other alternatives exist,
of course (such as whining about the unusable "density" value, then
either refusing to run, while suggesting the minimal value that is sane).

Feedback welcome,
david
-- 
David H. Wolfskill				david@catwhisker.org
To paraphrase David Hilbert, there can be no conflicts between the
discipline of systems administration and Microsoft, since they have
nothing in common.

To Unsubscribe: send mail to majordomo@FreeBSD.org
with "unsubscribe freebsd-current" in the body of the message




Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200210312230.g9VMUxni040707>