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