Find lost blocks in V6 filesystem
Larry Campbell
campbell at maynard.UUCP
Sun Mar 23 01:20:27 AEST 1986
V6 and V7 apparently have filesystem bug(s) that can result in a file
claiming to be n bytes long but actually owning many more than (n+511)/512
blocks. fsck doesn't help; everything seems consistent, but when you
add everything up you find that you're short several thousand blocks.
This program, originally written for V7 by Fred Toth, is a lifesaver.
It will find all the files that incorrectly own big chunks of the disk;
you can then copy the files (cp only copies up to the EOF pointer) and
delete the original to free up the space. I have modified it for V6
filesystems to run on my VENIX 2.0 system (V7 kernel with V6 filesystem).
Share and enjoy.
------------------------------cut here------------------------------
/*
* This posting is for those interested in the 'disappearing disk space'
* discussion in net.unix-wizards.
*
* Fred Toth
* Washburn Graphics, Inc.
* Charlotte, NC
* decvax!mcnc!unccvax!wgivax!fpt
*
* scani.c
*
* This program scans a v7 file system, looking for inodes
* that have more blocks allocated to them then they need
* based on the size field.
*
* It reads it's standard input and reports inode numbers.
* Ncheck can then be used to find the files.
* Copying them and deleting the original will free the blocks.
*
***********************************************************************
*
* Modified for V6 (VENIX, actually, V7 kernel with V6 filesystem)
* by Larry Campbell (maynard!campbell)
*
*/
#include <stdio.h>
#include <sys/param.h>
#include <sys/filsys.h>
#include <sys/ino.h>
struct filsys sb;
struct inode mynod;
#define NADDR 8 /* number of disk address in inode */
#define SINODE 32 /* size of an inode in bytes */
#define BLKSIZ 512 /* size of a disk block */
#define NBLKADR (BLKSIZ / (sizeof daddr_t)) /* disk addresses per block */
long ci, cii, ciii;
main()
{
int i;
unsigned toti, in;
long has, need, countb(), extra, totex, totb, size;
int files;
files = 0;
totb = totex = 0L;
lseek(0, (long) BLKSIZ, 0);
read(0, &sb, sizeof(struct filsys));
toti = (sb.s_isize - 2) * (BLKSIZ / SINODE);
printf("%u inodes\n", toti);
lseek(0, (long) BLKSIZ*2, 0);
in = 0;
while (toti--) {
in++;
lseek(0, (((long) in - 1L) * 32L) + (long) BLKSIZ*2, 0);
if (read(0, &mynod, sizeof(struct inode)) == NULL)
break;
if (mynod.i_mode) {
if (mynod.i_mode & IFCHR)
continue;
files++;
size = (((long) mynod.i_size0) << 16) + mynod.i_size1;
need = (size + (BLKSIZ-1)) / BLKSIZ;
if ((has = countb()) > need) {
extra = has - need;
totex += extra;
printf("i %u, needs %D, has %D, %D extra\n", in, need, has, extra);
}
totb += has;
}
}
printf("Did %u inodes, %d files\n", in, files);
printf("%D extra allocated blocks\n", totex);
printf("%D data, %D i, %D, ii, %D iii\n", totb, ci, cii, ciii);
}
long
countb()
{
int i;
long count, cindir(), cdoub(), ctrip();
count = 0;
if (mynod.i_mode & ILARG)
{
for (i = 0; i < 6; i++)
if (mynod.i_addr[i])
count += cindir(mynod.i_addr[i]);
if (mynod.i_addr[7])
count += cdoub(mynod.i_addr[7]);
}
else
for (i = 0; i < 7; i++)
if (mynod.i_addr[i])
count++;
return(count);
}
long
cindir(blk)
daddr_t blk;
{
long count;
daddr_t ib[256];
int i;
count = 0;
getblk(ib, blk);
ci++;
for (i = 0; i < 256; i++)
if (ib[i])
count++;
return(count);
}
getblk(p, no)
char *p;
daddr_t no;
{
lseek(0, ((long) no) * BLKSIZ, 0);
if (read(0, p, BLKSIZ) <= 0)
printf("bad read, b %D\n", no);
}
long
cdoub(blk)
daddr_t blk;
{
daddr_t dib[256];
long count;
int i;
count = 0;
getblk(dib, blk);
cii++;
for (i = 0; i < 256; i++)
if (dib[i])
count += cindir(dib[i]);
return(count);
}
long
ctrip(blk)
daddr_t blk;
{
daddr_t tib[256];
long count;
int i;
count = 0;
getblk(tib, blk);
ciii++;
for (i = 0; i < 256; i++)
if (tib[i])
count += cdoub(tib[i]);
return(count);
}
--
Larry Campbell The Boston Software Works, Inc.
ARPA: maynard.UUCP:campbell at harvard.ARPA 120 Fulton Street
UUCP: {harvard,cbosgd}!wjh12!maynard!campbell Boston MA 02109
More information about the Comp.sources.unix
mailing list