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