MCPcopy Create free account
hub / github.com/F-Stack/f-stack / cache_fplookup_trailingslash

Function cache_fplookup_trailingslash

freebsd/kern/vfs_cache.c:5394–5508  ·  view source on GitHub ↗

* Handle trailing slashes (e.g., "foo/"). * * If a trailing slash is found the terminal vnode must be a directory. * Regular lookup shortens the path by nulifying the first trailing slash and * sets the TRAILINGSLASH flag to denote this took place. There are several * checks on it performed later. * * Similarly to spurious slashes, lockless lookup handles this in a speculative * manner rel

Source from the content-addressed store, hash-verified

5392 * Only plain lookups are supported for now to restrict corner cases to handle.
5393 */
5394static int __noinline
5395cache_fplookup_trailingslash(struct cache_fpl *fpl)
5396{
5397#ifdef INVARIANTS
5398 size_t ni_pathlen;
5399#endif
5400 struct nameidata *ndp;
5401 struct componentname *cnp;
5402 struct namecache *ncp;
5403 struct vnode *tvp;
5404 char *cn_nameptr_orig, *cn_nameptr_slash;
5405 seqc_t tvp_seqc;
5406 u_char nc_flag;
5407
5408 ndp = fpl->ndp;
5409 cnp = fpl->cnp;
5410 tvp = fpl->tvp;
5411 tvp_seqc = fpl->tvp_seqc;
5412
5413 MPASS(fpl->dvp == fpl->tvp);
5414 KASSERT(cache_fpl_istrailingslash(fpl),
5415 ("%s: expected trailing slash at %p; string [%s]\n", __func__, fpl->nulchar - 1,
5416 cnp->cn_pnbuf));
5417 KASSERT(cnp->cn_nameptr[0] == '\0',
5418 ("%s: expected nul char at %p; string [%s]\n", __func__, &cnp->cn_nameptr[0],
5419 cnp->cn_pnbuf));
5420 KASSERT(cnp->cn_namelen == 0,
5421 ("%s: namelen 0 but got %ld; string [%s]\n", __func__, cnp->cn_namelen,
5422 cnp->cn_pnbuf));
5423 MPASS(cnp->cn_nameptr > cnp->cn_pnbuf);
5424
5425 if (cnp->cn_nameiop != LOOKUP) {
5426 return (cache_fpl_aborted(fpl));
5427 }
5428
5429 if (__predict_false(tvp->v_type != VDIR)) {
5430 if (!vn_seqc_consistent(tvp, tvp_seqc)) {
5431 return (cache_fpl_aborted(fpl));
5432 }
5433 cache_fpl_smr_exit(fpl);
5434 return (cache_fpl_handled_error(fpl, ENOTDIR));
5435 }
5436
5437 /*
5438 * Denote the last component.
5439 */
5440 ndp->ni_next = &cnp->cn_nameptr[0];
5441 MPASS(cache_fpl_islastcn(ndp));
5442
5443 /*
5444 * Unwind trailing slashes.
5445 */
5446 cn_nameptr_orig = cnp->cn_nameptr;
5447 while (cnp->cn_nameptr >= cnp->cn_pnbuf) {
5448 cnp->cn_nameptr--;
5449 if (cnp->cn_nameptr[0] != '/') {
5450 break;
5451 }

Callers 1

cache_fplookup_noentryFunction · 0.85

Calls 5

cache_fpl_islastcnFunction · 0.85
cache_fpl_pathlen_addFunction · 0.85
cache_fpl_checkpointFunction · 0.85
panicFunction · 0.70

Tested by

no test coverage detected