| 5251 | #endif |
| 5252 | |
| 5253 | static void |
| 5254 | cache_fplookup_parse(struct cache_fpl *fpl) |
| 5255 | { |
| 5256 | struct nameidata *ndp; |
| 5257 | struct componentname *cnp; |
| 5258 | struct vnode *dvp; |
| 5259 | char *cp; |
| 5260 | uint32_t hash; |
| 5261 | |
| 5262 | ndp = fpl->ndp; |
| 5263 | cnp = fpl->cnp; |
| 5264 | dvp = fpl->dvp; |
| 5265 | |
| 5266 | /* |
| 5267 | * Find the end of this path component, it is either / or nul. |
| 5268 | * |
| 5269 | * Store / as a temporary sentinel so that we only have one character |
| 5270 | * to test for. Pathnames tend to be short so this should not be |
| 5271 | * resulting in cache misses. |
| 5272 | * |
| 5273 | * TODO: fix this to be word-sized. |
| 5274 | */ |
| 5275 | KASSERT(&cnp->cn_nameptr[fpl->debug.ni_pathlen - 1] == fpl->nulchar, |
| 5276 | ("%s: mismatch between pathlen (%zu) and nulchar (%p != %p), string [%s]\n", |
| 5277 | __func__, fpl->debug.ni_pathlen, &cnp->cn_nameptr[fpl->debug.ni_pathlen - 1], |
| 5278 | fpl->nulchar, cnp->cn_pnbuf)); |
| 5279 | KASSERT(*fpl->nulchar == '\0', |
| 5280 | ("%s: expected nul at %p; string [%s]\n", __func__, fpl->nulchar, |
| 5281 | cnp->cn_pnbuf)); |
| 5282 | hash = cache_get_hash_iter_start(dvp); |
| 5283 | *fpl->nulchar = '/'; |
| 5284 | for (cp = cnp->cn_nameptr; *cp != '/'; cp++) { |
| 5285 | KASSERT(*cp != '\0', |
| 5286 | ("%s: encountered unexpected nul; string [%s]\n", __func__, |
| 5287 | cnp->cn_nameptr)); |
| 5288 | hash = cache_get_hash_iter(*cp, hash); |
| 5289 | continue; |
| 5290 | } |
| 5291 | *fpl->nulchar = '\0'; |
| 5292 | fpl->hash = cache_get_hash_iter_finish(hash); |
| 5293 | |
| 5294 | cnp->cn_namelen = cp - cnp->cn_nameptr; |
| 5295 | cache_fpl_pathlen_sub(fpl, cnp->cn_namelen); |
| 5296 | |
| 5297 | #ifdef INVARIANTS |
| 5298 | if (cnp->cn_namelen <= NAME_MAX) { |
| 5299 | if (fpl->hash != cache_get_hash(cnp->cn_nameptr, cnp->cn_namelen, dvp)) { |
| 5300 | panic("%s: mismatched hash for [%s] len %ld", __func__, |
| 5301 | cnp->cn_nameptr, cnp->cn_namelen); |
| 5302 | } |
| 5303 | } |
| 5304 | #endif |
| 5305 | |
| 5306 | /* |
| 5307 | * Hack: we have to check if the found path component's length exceeds |
| 5308 | * NAME_MAX. However, the condition is very rarely true and check can |
| 5309 | * be elided in the common case -- if an entry was found in the cache, |
| 5310 | * then it could not have been too long to begin with. |
no test coverage detected