Wed May 25 10:02:27 2022 UTC ()
lsof: don't need to keep track of the parent vnode kva, save some RAM


(tnn)
diff -r1.3 -r1.4 pkgsrc/sysutils/lsof/files/rnmt.c

cvs diff -r1.3 -r1.4 pkgsrc/sysutils/lsof/files/rnmt.c (expand / switch to unified diff)

--- pkgsrc/sysutils/lsof/files/rnmt.c 2022/05/25 09:48:58 1.3
+++ pkgsrc/sysutils/lsof/files/rnmt.c 2022/05/25 10:02:27 1.4
@@ -25,27 +25,26 @@ @@ -25,27 +25,26 @@
25/* 25/*
26 * rnmt.c - read NetBSD=>10-style red-black tree kernel name cache 26 * rnmt.c - read NetBSD=>10-style red-black tree kernel name cache
27 */ 27 */
28 28
29static int lnc_compare_nodes(void *, const void *, const void *); 29static int lnc_compare_nodes(void *, const void *, const void *);
30static int lnc_compare_key(void *, const void *, const void *); 30static int lnc_compare_key(void *, const void *, const void *);
31 31
32static rb_tree_t lnc_rbtree; 32static rb_tree_t lnc_rbtree;
33 33
34/* local name cache entry */ 34/* local name cache entry */
35struct lnc { 35struct lnc {
36 struct rb_node lnc_tree; /* red-black tree */ 36 struct rb_node lnc_tree; /* red-black tree */
37 KA_T lnc_vp; /* vnode address */ 37 KA_T lnc_vp; /* vnode address */
38 KA_T lnc_pvp; /* parent vnode address */ 
39 const struct lnc *lnc_plnc; /* parent lnc address */ 38 const struct lnc *lnc_plnc; /* parent lnc address */
40 int lnc_nlen; /* name length */ 39 int lnc_nlen; /* name length */
41 char lnc_name[NCHNAMLEN + 1]; /* name */ 40 char lnc_name[NCHNAMLEN + 1]; /* name */
42}; 41};
43 42
44static const rb_tree_ops_t lnc_rbtree_ops = { 43static const rb_tree_ops_t lnc_rbtree_ops = {
45 .rbto_compare_nodes = lnc_compare_nodes, 44 .rbto_compare_nodes = lnc_compare_nodes,
46 .rbto_compare_key = lnc_compare_key, 45 .rbto_compare_key = lnc_compare_key,
47 .rbto_node_offset = offsetof(struct lnc, lnc_tree), 46 .rbto_node_offset = offsetof(struct lnc, lnc_tree),
48 .rbto_context = NULL 47 .rbto_context = NULL
49}; 48};
50 49
51static int 50static int
@@ -71,36 +70,35 @@ lnc_compare_key(void *context, const voi @@ -71,36 +70,35 @@ lnc_compare_key(void *context, const voi
71 const KA_T vp = (KA_T)key; 70 const KA_T vp = (KA_T)key;
72 71
73 if (lnc->lnc_vp < vp) { 72 if (lnc->lnc_vp < vp) {
74 return -1; 73 return -1;
75 } 74 }
76 if (lnc->lnc_vp > vp) { 75 if (lnc->lnc_vp > vp) {
77 return 1; 76 return 1;
78 } 77 }
79 78
80 return 0; 79 return 0;
81} 80}
82 81
83static struct lnc * 82static struct lnc *
84ncache_enter_local(KA_T vp, KA_T pvp, const struct lnc *plnc, const struct namecache *nc) 83ncache_enter_local(KA_T vp, const struct lnc *plnc, const struct namecache *nc)
85{ 84{
86 struct lnc *lnc; 85 struct lnc *lnc;
87 86
88 lnc = malloc(sizeof(*lnc)); 87 lnc = malloc(sizeof(*lnc));
89 if (!lnc) { 88 if (!lnc) {
90 errx(1, "can't allocate local name cache entry\n"); 89 errx(1, "can't allocate local name cache entry\n");
91 } 90 }
92 lnc->lnc_vp = vp; 91 lnc->lnc_vp = vp;
93 lnc->lnc_pvp = pvp; 
94 lnc->lnc_plnc = plnc; 92 lnc->lnc_plnc = plnc;
95 lnc->lnc_nlen = nc->nc_nlen; 93 lnc->lnc_nlen = nc->nc_nlen;
96 memcpy(lnc->lnc_name, nc->nc_name, lnc->lnc_nlen); 94 memcpy(lnc->lnc_name, nc->nc_name, lnc->lnc_nlen);
97 lnc->lnc_name[lnc->lnc_nlen] = 0; 95 lnc->lnc_name[lnc->lnc_nlen] = 0;
98 96
99 rb_tree_insert_node(&lnc_rbtree, lnc); 97 rb_tree_insert_node(&lnc_rbtree, lnc);
100 98
101 return lnc; 99 return lnc;
102} 100}
103 101
104static int 102static int
105sanity_check_vnode_impl(const struct vnode_impl *vi) 103sanity_check_vnode_impl(const struct vnode_impl *vi)
106{ 104{
@@ -119,72 +117,72 @@ sanity_check_namecache(const struct name @@ -119,72 +117,72 @@ sanity_check_namecache(const struct name
119 if (nc->nc_nlen > NCHNAMLEN) 117 if (nc->nc_nlen > NCHNAMLEN)
120 return -1; 118 return -1;
121 119
122 if (nc->nc_nlen == 1 && nc->nc_name[0] == '.') 120 if (nc->nc_nlen == 1 && nc->nc_name[0] == '.')
123 return -1; 121 return -1;
124 122
125 if (nc->nc_nlen == 2 && nc->nc_name[0] == '.' && nc->nc_name[1] == '.') 123 if (nc->nc_nlen == 2 && nc->nc_name[0] == '.' && nc->nc_name[1] == '.')
126 return -1; 124 return -1;
127 125
128 return 0; 126 return 0;
129} 127}
130 128
131static void 129static void
132ncache_walk(KA_T ncp, KA_T pvp, const struct lnc *plnc) 130ncache_walk(KA_T ncp, const struct lnc *plnc)
133{ 131{
134 struct l_nch *lc; 132 struct l_nch *lc;
135 static struct vnode_impl vi; 133 static struct vnode_impl vi;
136 static struct namecache nc; 134 static struct namecache nc;
137 struct lnc *lnc; 135 struct lnc *lnc;
138 KA_T vp; 136 KA_T vp;
139 KA_T left, right; 137 KA_T left, right;
140 138
141 if (kread(ncp, (char *)&nc, sizeof(nc))) { 139 if (kread(ncp, (char *)&nc, sizeof(nc))) {
142 return; 140 return;
143 } 141 }
144 vp = (KA_T)nc.nc_vp; 142 vp = (KA_T)nc.nc_vp;
145 if (kread(vp, (char *)&vi, sizeof(vi))) { 143 if (kread(vp, (char *)&vi, sizeof(vi))) {
146 vi.vi_vnode.v_type = VBAD; 144 vi.vi_vnode.v_type = VBAD;
147 } 145 }
148 left = (KA_T)nc.nc_tree.rb_nodes[0]; 146 left = (KA_T)nc.nc_tree.rb_nodes[0];
149 right = (KA_T)nc.nc_tree.rb_nodes[1]; 147 right = (KA_T)nc.nc_tree.rb_nodes[1];
150 if (sanity_check_vnode_impl(&vi) == 0 && sanity_check_namecache(&nc) == 0) { 148 if (sanity_check_vnode_impl(&vi) == 0 && sanity_check_namecache(&nc) == 0) {
151 lnc = ncache_enter_local(vp, pvp, plnc, &nc); 149 lnc = ncache_enter_local(vp, plnc, &nc);
152 if (vi.vi_vnode.v_type == VDIR && vi.vi_nc_tree.rbt_root != NULL) { 150 if (vi.vi_vnode.v_type == VDIR && vi.vi_nc_tree.rbt_root != NULL) {
153 ncache_walk((KA_T)vi.vi_nc_tree.rbt_root, ncp, lnc); 151 ncache_walk((KA_T)vi.vi_nc_tree.rbt_root, lnc);
154 } 152 }
155 } 153 }
156 if (left) 154 if (left)
157 ncache_walk(left, pvp, plnc); 155 ncache_walk(left, plnc);
158 if (right) 156 if (right)
159 ncache_walk(right, pvp, plnc); 157 ncache_walk(right, plnc);
160} 158}
161 159
162void 160void
163ncache_load() 161ncache_load()
164{ 162{
165 KA_T rootvnode_addr; 163 KA_T rootvnode_addr;
166 struct vnode_impl vi; 164 struct vnode_impl vi;
167 165
168 rootvnode_addr = (KA_T)0; 166 rootvnode_addr = (KA_T)0;
169 if (get_Nl_value("rootvnode", (struct drive_Nl *)NULL, &rootvnode_addr) < 0 167 if (get_Nl_value("rootvnode", (struct drive_Nl *)NULL, &rootvnode_addr) < 0
170 || !rootvnode_addr 168 || !rootvnode_addr
171 || kread((KA_T)rootvnode_addr, (char *)&rootvnode_addr, sizeof(rootvnode_addr)) 169 || kread((KA_T)rootvnode_addr, (char *)&rootvnode_addr, sizeof(rootvnode_addr))
172 || kread((KA_T)rootvnode_addr, (char *)&vi, sizeof(vi))) { 170 || kread((KA_T)rootvnode_addr, (char *)&vi, sizeof(vi))) {
173 errx(1, "can't read rootvnode\n"); 171 errx(1, "can't read rootvnode\n");
174 } 172 }
175 173
176 rb_tree_init(&lnc_rbtree, &lnc_rbtree_ops); 174 rb_tree_init(&lnc_rbtree, &lnc_rbtree_ops);
177 ncache_walk((KA_T)vi.vi_nc_tree.rbt_root, 0, 0); 175 ncache_walk((KA_T)vi.vi_nc_tree.rbt_root, 0);
178} 176}
179 177
180static void 178static void
181build_path(char **buf, size_t *remaining, const struct lnc *lnc) 179build_path(char **buf, size_t *remaining, const struct lnc *lnc)
182{ 180{
183 size_t len; 181 size_t len;
184 182
185 if (lnc == NULL) 183 if (lnc == NULL)
186 return; 184 return;
187 185
188 build_path(buf, remaining, lnc->lnc_plnc); 186 build_path(buf, remaining, lnc->lnc_plnc);
189 if (remaining == 0) { 187 if (remaining == 0) {
190 return; 188 return;