xref: /freebsd/tools/diag/dumpvfscache/dumpvfscache.c (revision daf1cffce2e07931f27c6c6998652e90df6ba87e)
1 #include <stdio.h>
2 #include <stdlib.h>
3 #include <unistd.h>
4 #include <fcntl.h>
5 #include <kvm.h>
6 #include <nlist.h>
7 #include <sys/uio.h>
8 #include <sys/namei.h>
9 #include <sys/param.h>
10 #include <sys/time.h>
11 #include <sys/vnode.h>
12 /*----------------------------------*/
13 static u_int crc16_table[16] = {
14     0x0000, 0xCC01, 0xD801, 0x1400,
15     0xF001, 0x3C00, 0x2800, 0xE401,
16     0xA001, 0x6C00, 0x7800, 0xB401,
17     0x5000, 0x9C01, 0x8801, 0x4400
18 };
19 
20 static u_short
21 wlpsacrc(u_char *buf, u_int len)
22 {
23     u_short     crc = 0;
24     int         i, r1;
25 
26     for (i = 0; i < len; i++, buf++) {
27         /* lower 4 bits */
28         r1 = crc16_table[crc & 0xF];
29         crc = (crc >> 4) & 0x0FFF;
30         crc = crc ^ r1 ^ crc16_table[*buf & 0xF];
31 
32         /* upper 4 bits */
33         r1 = crc16_table[crc & 0xF];
34         crc = (crc >> 4) & 0x0FFF;
35         crc = crc ^ r1 ^ crc16_table[(*buf >> 4) & 0xF];
36     }
37     return(crc);
38 }
39 
40 /*----------------------------------*/
41 struct nlist nl[] = {
42 	{ "_nchash", 0},
43 	{ "_nchashtbl", 0},
44 	{ 0, 0 },
45 };
46 
47 int histo[2047];
48 int histn[2047];
49 int *newbucket;
50 
51 int
52 main(int argc, char **argv)
53 {
54 	int nchash, i, j, k, kn;
55 	int nb, p1, p2;
56 	u_long p;
57 	LIST_HEAD(nchashhead, namecache) *nchashtbl;
58 	struct namecache *nc;
59 	struct vnode vn;
60 
61 	kvm_t *kvm = kvm_open(0, 0, 0, O_RDONLY, 0);
62 
63 	printf("kvm: %p\n", kvm);
64 	printf("kvm_nlist: %d\n", kvm_nlist(kvm, nl));
65 	kvm_read(kvm, nl[0].n_value, &nchash, sizeof nchash);
66 	nchash++;
67 	nchashtbl = malloc(nchash * sizeof *nchashtbl);
68 	nc = malloc(sizeof *nc + 400);
69 	newbucket = malloc(nchash * sizeof (int));
70 	memset(newbucket, 0, nchash * sizeof (int));
71 	kvm_read(kvm, nl[1].n_value, &p, sizeof p);
72 	kvm_read(kvm, p, nchashtbl, nchash * sizeof *nchashtbl);
73 	for (i=0; i < nchash; i++) {
74 #if 0
75 		printf("%d\n", i);
76 #endif
77 		nb=0;
78 		p = (u_long)LIST_FIRST(nchashtbl+i);
79 		while (p) {
80 			nb++;
81 			kvm_read(kvm, p, nc, sizeof *nc + 400);
82 			kvm_read(kvm, (u_long)nc->nc_dvp, &vn, sizeof vn);
83 			nc->nc_name[nc->nc_nlen] = '\0';
84 			for (j=k=kn=0;nc->nc_name[j];j++) {
85 				k+= nc->nc_name[j];
86 				kn <<= 1;
87 				kn+= nc->nc_name[j];
88 			}
89 			/*
90 			kn = k;
91 			*/
92 			kn = wlpsacrc(nc->nc_name,nc->nc_nlen);
93 
94 			/* kn += (u_long)vn.v_data >> 8;  */
95 			/* kn += (u_long)nc->nc_dvp >> 7;    */
96 			kn += vn.v_id;
97 			kn &= (nchash - 1);
98 			newbucket[kn]++;
99 #if 1
100 			printf("%4d  dvp %08x  hash %08x  vp %08x  id %08x  name <%s>\n",
101 				i,nc->nc_dvp, k, nc->nc_vp, vn.v_id, nc->nc_name);
102 #endif
103 			p = (u_long)LIST_NEXT(nc, nc_hash);
104 		}
105 		histo[nb]++;
106 	}
107 	for (i=0; i < nchash; i++) {
108 		histn[newbucket[i]]++;
109 	}
110 	p1=p2 = 0;
111 	for (i=0;i<30;i++) {
112 		p1 += histo[i] * i;
113 		p2 += histn[i] * i;
114 		if (histo[i] || histn[i])
115 			printf("H%02d %4d %4d / %4d %4d\n",i,histo[i], p1 , histn[i], p2);
116 	}
117 
118 	return (0);
119 }
120 
121