ast@cs.vu.nl (Andy Tanenbaum) (10/25/89)
Here is df.c for larger disks. Since my own disk is 20M, it is hard to
create 32M and larger partitions. Could somebody please give this a test.
Andy Tanenbaum (ast@cs.vu.nl)
/* df - disk free block printout Author: Andy Tanenbaum */
#include <minix/const.h>
#include <minix/type.h>
#include <fs/const.h>
#include <fs/type.h>
#include <fs/super.h>
#define block_nr long /* Allow big devices even if FS doesn't */
#include <sys/types.h>
#include <sys/stat.h>
#include <errno.h>
#include <stdio.h>
extern int errno;
char *mtab = "/etc/mtab";
#define REPORT 0
#define SILENT 1
main(argc, argv)
int argc;
char *argv[];
{
register int i;
sync(); /* have to make sure disk is up-to-date */
fprintf(stdout,"\nDevice Inodes Inodes Inodes Blocks Blocks Blocks ");
if (argc == 1)
fprintf(stdout, "Mounted on\n");
else
fprintf(stdout, "\n");
fprintf(stdout," total used free total used free\n");
fprintf(stdout," ----- ----- ----- ----- ----- -----\n");
if (argc == 1) defaults();
for (i = 1; i < argc; i++)
df(argv[i], "", SILENT);
exit(0);
}
#define percent(num, tot) ((int) ((100L * (num) + ((tot) - 1)) / (tot)))
df(name, mnton, silent)
char *name, *mnton;
int silent;
{
register int fd;
inode_nr i_count, z_count;
block_nr totblocks, busyblocks;
int i, j;
char buf[BLOCK_SIZE], *s0;
struct super_block super, *sp;
if ((fd = open(name, 0)) < 0) {
if (!silent) {
int e = errno;
fprintf(stderr, "df: ");
errno = e;
perror(name);
}
return;
}
lseek(fd, (long) BLOCK_SIZE, 0); /* skip boot block */
if (read(fd, &super, SUPER_SIZE) != SUPER_SIZE) {
fprintf(stderr, "df: Can't read super block of %s\n", name);
close(fd);
return;
}
lseek(fd, (long) BLOCK_SIZE * 2L, 0); /* skip rest of super block */
sp = &super;
if (sp->s_magic != SUPER_MAGIC) {
fprintf(stderr, "df: %s: Not a valid file system\n", name);
close(fd);
return;
}
i_count = bit_count(sp->s_imap_blocks, sp->s_ninodes + 1, fd);
if (i_count == -1) {
fprintf(stderr, "df: Can't find bit maps of %s\n", name);
close(fd);
return;
}
i_count--; /* There is no inode 0. */
z_count = bit_count(sp->s_zmap_blocks, sp->s_nzones, fd);
if (z_count == -1) {
fprintf(stderr, "df: Can't find bit maps of %s\n", name);
close(fd);
return;
}
totblocks = (block_nr) sp->s_nzones << sp->s_log_zone_size;
busyblocks = (block_nr) z_count << sp->s_log_zone_size;
/* Print results. */
fprintf(stdout, "%s", name);
j = 10 - strlen(name);
while (j > 0) {
fprintf(stdout, " ");
j--;
}
fprintf(stdout, " %5u %5u %5u %7ld %7ld %7ld %s\n",
sp->s_ninodes, /* total inodes */
i_count, /* inodes used */
sp->s_ninodes - i_count, /* inodes free */
totblocks, /* total blocks */
busyblocks, /* blocks used */
totblocks - busyblocks, /* blocsk free */
strcmp(mnton, "device") == 0 ? "(root dev)" : mnton
);
close(fd);
}
bit_count(blocks, bits, fd)
int blocks;
int bits;
int fd;
{
register int i, b;
int busy, count, w;
int *wptr, *wlim;
int buf[BLOCK_SIZE / sizeof(int)];
/* Loop on blocks, reading one at a time and counting bits. */
busy = 0;
count = 0;
for (i = 0; i < blocks; i++) {
if (read(fd, buf, BLOCK_SIZE) != BLOCK_SIZE) return(-1);
wptr = &buf[0];
wlim = &buf[BLOCK_SIZE / sizeof(int)];
/* Loop on the words of a block */
while (wptr != wlim) {
w = *wptr++;
/* Loop on the bits of a word. */
for (b = 0; b < 8 * sizeof(int); b++) {
if ((w >> b) & 1) busy++;
if (++count == bits) return (busy);
}
}
}
return(0);
}
char mtabbuf[1024];
int mtabcnt;
getname(d, m)
char **d, **m;
{
int c;
static char *mp = mtabbuf;
*d = mp;
*m = "";
do {
if (--mtabcnt < 0) exit(0);
c = *mp++;
if (c == ' ') {
mp[-1] = 0;
*m = mp;
}
} while (c != '\n');
mp[-1] = 0;
}
defaults()
{
/* Use the root file system and all mounted file systems. */
char *dev, *dir;
close(0);
if (open(mtab, 0) < 0 || (mtabcnt = read(0, mtabbuf, sizeof(mtabbuf)))<= 0) {
fprintf(stderr, "df: cannot read %s\n", mtab);
exit(1);
}
/* Read /etc/mtab and iterate on the lines. */
while (1) {
getname(&dev, &dir); /* getname exits upon hitting EOF */
df(dev, dir, REPORT);
}
}
static int fd, w, left;
static char fill;
static void wr(a, n)
char *a;
int n;
{
if (left && n > 0) write(fd, a, n);
while (w > n) {
write(fd, &fill, 1);
--w;
}
if (!left && n > 0) write(fd, a, n);
}
static void pr_n(neg, n)
int neg;
unsigned long n;
{
char a[3 * sizeof(n) + 1], *pa = a + sizeof(a);
do
*--pa = '0' + n % 10;
while ((n /= 10) != 0);
if (neg) *--pa = '-';
wr(pa, a + sizeof(a) - pa);
}
static void pr_i(i)
long i;
{
int neg = 0;
if (i < 0) {
neg = 1;
i = -i;
}
pr_n(neg, (unsigned long) i);
}