summaryrefslogtreecommitdiffstats
path: root/tools/diag/dumpvfscache/dumpvfscache.c
blob: 93dd72c1b8fb2f501898a8f57bfc9ec3210664e0 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
/* $FreeBSD$ */
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#include <kvm.h>
#include <nlist.h>
#include <sys/uio.h>
#include <sys/namei.h>
#include <sys/param.h>
#include <sys/time.h>
#include <sys/vnode.h>
/*----------------------------------*/
static u_int crc16_table[16] = { 
    0x0000, 0xCC01, 0xD801, 0x1400,
    0xF001, 0x3C00, 0x2800, 0xE401,
    0xA001, 0x6C00, 0x7800, 0xB401,
    0x5000, 0x9C01, 0x8801, 0x4400 
};

static u_short
wlpsacrc(u_char *buf, u_int len)
{
    u_short     crc = 0;
    int         i, r1;
    
    for (i = 0; i < len; i++, buf++) {
        /* lower 4 bits */
        r1 = crc16_table[crc & 0xF];
        crc = (crc >> 4) & 0x0FFF;
        crc = crc ^ r1 ^ crc16_table[*buf & 0xF];
        
        /* upper 4 bits */
        r1 = crc16_table[crc & 0xF];
        crc = (crc >> 4) & 0x0FFF;
        crc = crc ^ r1 ^ crc16_table[(*buf >> 4) & 0xF];
    }
    return(crc);
}

/*----------------------------------*/
struct nlist nl[] = {
	{ "_nchash", 0},
	{ "_nchashtbl", 0},
	{ 0, 0 },
};

int histo[2047];
int histn[2047];
int *newbucket;

int
main(int argc, char **argv)
{
	int nchash, i, j, k, kn;
	int nb, p1, p2;
	u_long p;
	LIST_HEAD(nchashhead, struct namecache) *nchashtbl;
	struct namecache *nc;
	struct vnode vn;

	kvm_t *kvm = kvm_open(0, 0, 0, O_RDONLY, 0);

	printf("kvm: %p\n", kvm);
	printf("kvm_nlist: %d\n", kvm_nlist(kvm, nl));
	kvm_read(kvm, nl[0].n_value, &nchash, sizeof nchash);
	nchash++;
	nchashtbl = malloc(nchash * sizeof *nchashtbl);
	nc = malloc(sizeof *nc + 400);
	newbucket = malloc(nchash * sizeof (int));
	memset(newbucket, 0, nchash * sizeof (int));
	kvm_read(kvm, nl[1].n_value, &p, sizeof p);
	kvm_read(kvm, p, nchashtbl, nchash * sizeof *nchashtbl);
	for (i=0; i < nchash; i++) {
#if 0
		printf("%d\n", i);
#endif
		nb=0;
		p = (u_long)LIST_FIRST(nchashtbl+i);
		while (p) {
			nb++;
			kvm_read(kvm, p, nc, sizeof *nc + 400);
			kvm_read(kvm, (u_long)nc->nc_dvp, &vn, sizeof vn);
			nc->nc_name[nc->nc_nlen] = '\0';
			for (j=k=kn=0;nc->nc_name[j];j++) {
				k+= nc->nc_name[j];
				kn <<= 1;
				kn+= nc->nc_name[j];
			}
			/*
			kn = k;
			*/
			kn = wlpsacrc(nc->nc_name,nc->nc_nlen);

			/* kn += (u_long)vn.v_data >> 8;  */
			/* kn += (u_long)nc->nc_dvp >> 7;    */
			kn += vn.v_id; 
			kn &= (nchash - 1);
			newbucket[kn]++;
#if 1
			printf("%4d  dvp %08x  hash %08x  vp %08x  id %08x  name <%s>\n",
				i,nc->nc_dvp, k, nc->nc_vp, vn.v_id, nc->nc_name);
#endif
			p = (u_long)LIST_NEXT(nc, nc_hash);
		}
		histo[nb]++;
	}
	for (i=0; i < nchash; i++) {
		histn[newbucket[i]]++;
	}
	p1=p2 = 0;
	for (i=0;i<30;i++) {
		p1 += histo[i] * i;
		p2 += histn[i] * i;
		if (histo[i] || histn[i])
			printf("H%02d %4d %4d / %4d %4d\n",i,histo[i], p1 , histn[i], p2);
	}
		
	return (0);
}

OpenPOWER on IntegriCloud