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