| @@ -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 | |
29 | static int lnc_compare_nodes(void *, const void *, const void *); | | 29 | static int lnc_compare_nodes(void *, const void *, const void *); |
30 | static int lnc_compare_key(void *, const void *, const void *); | | 30 | static int lnc_compare_key(void *, const void *, const void *); |
31 | | | 31 | |
32 | static rb_tree_t lnc_rbtree; | | 32 | static rb_tree_t lnc_rbtree; |
33 | | | 33 | |
34 | /* local name cache entry */ | | 34 | /* local name cache entry */ |
35 | struct lnc { | | 35 | struct 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 | |
44 | static const rb_tree_ops_t lnc_rbtree_ops = { | | 43 | static 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 | |
51 | static int | | 50 | static 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 | |
83 | static struct lnc * | | 82 | static struct lnc * |
84 | ncache_enter_local(KA_T vp, KA_T pvp, const struct lnc *plnc, const struct namecache *nc) | | 83 | ncache_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 | |
104 | static int | | 102 | static int |
105 | sanity_check_vnode_impl(const struct vnode_impl *vi) | | 103 | sanity_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 | |
131 | static void | | 129 | static void |
132 | ncache_walk(KA_T ncp, KA_T pvp, const struct lnc *plnc) | | 130 | ncache_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 | |
162 | void | | 160 | void |
163 | ncache_load() | | 161 | ncache_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 | |
180 | static void | | 178 | static void |
181 | build_path(char **buf, size_t *remaining, const struct lnc *lnc) | | 179 | build_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; |