NetBSD-Users archive

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

Re: Unable to fsck 4.5TB FFSv2 fs



In article <Pine.NEB.4.64.0809231024100.16305%ugly.precedence.co.uk@localhost>,
Stephen Borrill  <netbsd%precedence.co.uk@localhost> wrote:
>I have:
>
>ld1 at aac0 unit 1: RAID 5
>ld1: 4656 GB, 607897 cyl, 255 head, 63 sec, 512 bytes/sect x 9765867520 
>sectors
>
>Which I formatted with:
>newfs -O 2 -f 4096 -b 32768 -I -F -s 9765867520 /dev/rld1d
>
>This worked fine, but apparently (the machine is at a customer's) it 
>locked and so they power-cycled it and thus it wants to fsck (NetBSD 4.0 
>so no WAPBL).
>
>This is giving:
>** /dev/rld1d
>** Last Mounted on /usr/backup
>** Phase 1 - Check Blocks and Sizes
>cannot alloc 1243616332 bytes for inoinfo
>
>The machines has 1024MB RAM and I have swap configured:
>Device      512-blocks     Used    Avail Capacity  Priority
>/dev/ld0b      8401995        0  8401995     0%    0
>
>and have ulimited most things:
># ulimit -a
>time(seconds)        unlimited
>file(blocks)         unlimited
>data(kbytes)         3145728
>stack(kbytes)        2048
>coredump(blocks)     unlimited
>memory(kbytes)       3145728
>locked memory(kbytes) 339180
>process(processes)   160
>nofiles(descriptors) 64
>sbsize(bytes)        unlimited
>

Can you try this patch? It should reduce the total space needed, so if you die
in the second alloc, this should probably fix it. I have not tested it, so you
are on your own if it eats your disk, but visually it looks safe.

christos

Index: pass1.c
===================================================================
RCS file: /cvsroot/src/sbin/fsck_ffs/pass1.c,v
retrieving revision 1.44
diff -u -u -r1.44 pass1.c
--- pass1.c     23 Feb 2008 21:41:48 -0000      1.44
+++ pass1.c     23 Sep 2008 17:30:22 -0000
@@ -66,7 +66,8 @@
 void
 pass1(void)
 {
-       ino_t inumber, inosused;
+       ino_t inumber, inosused, ninosused;
+       size_t inospace;
        int c;
        daddr_t i, cgd;
        struct inodesc idesc;
@@ -151,12 +152,13 @@
                        inostathead[c].il_stat = 0;
                        continue;
                }
-               info = calloc((unsigned)inosused, sizeof(struct inostat));
+               inospace = inosused * sizeof(*info);
+               info = malloc(inospace);
                if (info == NULL) {
-                       pfatal("cannot alloc %u bytes for inoinfo\n",
-                           (unsigned)(sizeof(struct inostat) * inosused));
+                       pfatal("cannot alloc %zu bytes for inoinfo\n", 
inospace);
                        exit(FSCK_EXIT_CHECK_FAILED);
                }
+               (void)memset(info, 0, inospace);
                inostathead[c].il_stat = info;
                /*
                 * Scan the allocated inodes.
@@ -178,24 +180,28 @@
                 * really found.
                 */
                if (lastino < (c * sblock->fs_ipg))
-                       inosused = 0;
+                       ninosused = 0;
                else
-                       inosused = lastino - (c * sblock->fs_ipg);
-               inostathead[c].il_numalloced = inosused;
-               if (inosused == 0) {
+                       ninosused = lastino - (c * sblock->fs_ipg);
+               inostathead[c].il_numalloced = ninosused;
+               if (ninosused == 0) {
                        free(inostathead[c].il_stat);
                        inostathead[c].il_stat = 0;
                        continue;
                }
-               info = calloc((unsigned)inosused, sizeof(struct inostat));
-               if (info == NULL) {
-                       pfatal("cannot alloc %u bytes for inoinfo\n",
-                           (unsigned)(sizeof(struct inostat) * inosused));
-                       exit(FSCK_EXIT_CHECK_FAILED);
+               if (ninosused != inosused) {
+                       struct ninostats *ninfo;
+                       size_t ninospace = ninosused * sizeof(*ninfo);
+                       ninfo = realloc(info, ninosused);
+                       if (ninfo == NULL) {
+                               pfatal("cannot realloc %zu bytes to %zu for 
inoinfo\n",
+                                   inospace, ninospace);
+                               exit(FSCK_EXIT_CHECK_FAILED);
+                       }
+                       if (ninosused > inosused)
+                               (void)memset(&ninfo[inosused], 0, ninospace - 
inospace);
+                       inostathead[c].il_stat = ninfo;
                }
-               memmove(info, inostathead[c].il_stat, inosused * sizeof(*info));
-               free(inostathead[c].il_stat);
-               inostathead[c].il_stat = info;
        }
 #ifdef PROGRESS
        if (!preen)



Home | Main Index | Thread Index | Old Index