tech-kern archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

Re: 6.0_BETA: Extreamly slow newfs_ext2fs on 60Gb USB stick



> For a number of reasons I decided to use ext2 filesystem on 60Gb memory
> stick.
 :
> Unfortunately newfs_ext2fs works extreamly slowly

newfs_ext2fs(8) was intended to prepare boot partitions for
Linux based appliances (like cobalt) without GPLed tools,
so its implementation is quite dumb and it doesn't have
any I/O optimazations.

There are two possible problems:

 (1) newfs_ext2fs(8) has too many zero'ing ops to erase possible
     superblock backup leftovers
   -> The attached patch (which makes newfs_ext2fs(8) zap fewer block)
      omits most write ops.

 (2) ext2fs has a fixed block group (cylinder group in FFS) size
     so large fs will have too many sparse block group structures
     to be initialized
   -> Using REV1 (newfs_ext2fs -O 1) could reduce blocks
      superblock backups) to be written during initialization.

Trying mke2fs in e2fsprogs (available in pkgsrc) might also be worth.

---
Izumi Tsutsui


Index: mke2fs.c
===================================================================
RCS file: /cvsroot/src/sbin/newfs_ext2fs/mke2fs.c,v
retrieving revision 1.14
diff -u -p -r1.14 mke2fs.c
--- mke2fs.c    10 Sep 2010 15:51:20 -0000      1.14
+++ mke2fs.c    2 Mar 2012 16:30:03 -0000
@@ -124,7 +124,7 @@ __RCSID("$NetBSD: mke2fs.c,v 1.14 2010/0
 #include "extern.h"
 
 static void initcg(uint);
-static void zap_old_sblock(daddr_t);
+static void zap_old_sblock(int);
 static uint cgoverhead(uint);
 static int fsinit(const struct timeval *);
 static int makedir(struct ext2fs_direct *, int);
@@ -552,7 +552,7 @@ mke2fs(const char *fsys, int fi, int fo)
 
        if (!Nflag) {
                static const uint pbsize[] = { 1024, 2048, 4096, 0 };
-               uint pblock, epblock;
+               uint pblock;
                /*
                 * Validate the given file system size.
                 * Verify that its last block can actually be accessed.
@@ -566,19 +566,23 @@ mke2fs(const char *fsys, int fi, int fo)
                /*
                 * Ensure there is nothing that looks like a filesystem
                 * superblock anywhere other than where ours will be.
-                * If fsck_ext2fs finds the wrong one all hell breaks loose!
                 *
-                * XXX: needs to check how fsck_ext2fs programs even
-                *      on other OSes determine alternate superblocks
+                * Ext2fs superblock is always placed at the same SBOFF,
+                * so we just zap possible first backups.
                 */
                for (i = 0; pbsize[i] != 0; i++) {
-                       epblock = (uint64_t)bcount * bsize / pbsize[i];
-                       for (pblock = ((pbsize[i] == SBSIZE) ? 1 : 0);
-                           pblock < epblock;
-                           pblock += pbsize[i] * NBBY /* bpg */)
-                               zap_old_sblock((daddr_t)pblock *
-                                   pbsize[i] / sectorsize);
+                       pblock = (pbsize[i] > BBSIZE) ? 0 : 1;  /* 1st dblk */
+                       pblock += pbsize[i] * NBBY;             /* next bg */
+                       /* zap first backup */
+                       zap_old_sblock(pblock * pbsize[i]);
                }
+               /*
+                * Also zap possbile FFS magic leftover to prevent
+                * kernel vfs_mountroot() and bootloadres from mis-recognizing
+                * this file system as FFS.
+                */
+               zap_old_sblock(8192);   /* SBLOCK_UFS1 */
+               zap_old_sblock(65536);  /* SBLOCK_UFS2 */
        }
 
        if (verbosity >= 3)
@@ -769,9 +773,9 @@ initcg(uint cylno)
  * Zap possible lingering old superblock data
  */
 static void
-zap_old_sblock(daddr_t sec)
+zap_old_sblock(int sblkoff)
 {
-       static daddr_t cg0_data;
+       static int cg0_data;
        uint32_t oldfs[SBSIZE / sizeof(uint32_t)];
        static const struct fsm {
                uint32_t offset;
@@ -793,24 +797,25 @@ zap_old_sblock(daddr_t sec)
                return;
 
        /* don't override data before superblock */
-       if (sec < SBOFF / sectorsize)
+       if (sblkoff < SBOFF)
                return;
 
        if (cg0_data == 0) {
                cg0_data =
                    ((daddr_t)sblock.e2fs.e2fs_first_dblock + cgoverhead(0)) *
-                   sblock.e2fs_bsize / sectorsize;
+                   sblock.e2fs_bsize;
        }
 
        /* Ignore anything that is beyond our filesystem */
-       if (sec >= fssize)
+       if (sblkoff / sectorsize >= fssize)
                return;
        /* Zero anything inside our filesystem... */
-       if (sec >= sblock.e2fs.e2fs_first_dblock * bsize / sectorsize) {
+       if (sblkoff >= sblock.e2fs.e2fs_first_dblock * bsize) {
                /* ...unless we will write that area anyway */
-               if (sec >= cg0_data)
+               if (sblkoff >= cg0_data)
                        /* assume iobuf is zero'ed here */
-                       wtfs(sec, roundup(SBSIZE, sectorsize), iobuf);
+                       wtfs(sblkoff / sectorsize,
+                           roundup(SBSIZE, sectorsize), iobuf);
                return;
        }
 
@@ -820,7 +825,7 @@ zap_old_sblock(daddr_t sec)
         * XXX: ext2fs won't preserve data after SBOFF,
         *      but first_dblock could have a different value.
         */
-       rdfs(sec, sizeof(oldfs), &oldfs);
+       rdfs(sblkoff / sectorsize, sizeof(oldfs), &oldfs);
        for (fsm = fs_magics;; fsm++) {
                uint32_t v;
                if (fsm->mask == 0)
@@ -833,7 +838,7 @@ zap_old_sblock(daddr_t sec)
 
        /* Just zap the magic number */
        oldfs[fsm->offset] = 0;
-       wtfs(sec, sizeof(oldfs), &oldfs);
+       wtfs(sblkoff / sectorsize, sizeof(oldfs), &oldfs);
 }
 
 /*


Home | Main Index | Thread Index | Old Index