| 4974 | } |
| 4975 | |
| 4976 | static int |
| 4977 | cache_fplookup_next(struct cache_fpl *fpl) |
| 4978 | { |
| 4979 | struct componentname *cnp; |
| 4980 | struct namecache *ncp; |
| 4981 | struct vnode *dvp, *tvp; |
| 4982 | u_char nc_flag; |
| 4983 | uint32_t hash; |
| 4984 | int error; |
| 4985 | |
| 4986 | cnp = fpl->cnp; |
| 4987 | dvp = fpl->dvp; |
| 4988 | hash = fpl->hash; |
| 4989 | |
| 4990 | if (__predict_false(cnp->cn_nameptr[0] == '.')) { |
| 4991 | if (cnp->cn_namelen == 1) { |
| 4992 | return (cache_fplookup_dot(fpl)); |
| 4993 | } |
| 4994 | if (cnp->cn_namelen == 2 && cnp->cn_nameptr[1] == '.') { |
| 4995 | return (cache_fplookup_dotdot(fpl)); |
| 4996 | } |
| 4997 | } |
| 4998 | |
| 4999 | MPASS(!cache_fpl_isdotdot(cnp)); |
| 5000 | |
| 5001 | CK_SLIST_FOREACH(ncp, (NCHHASH(hash)), nc_hash) { |
| 5002 | if (ncp->nc_dvp == dvp && ncp->nc_nlen == cnp->cn_namelen && |
| 5003 | !bcmp(ncp->nc_name, cnp->cn_nameptr, ncp->nc_nlen)) |
| 5004 | break; |
| 5005 | } |
| 5006 | |
| 5007 | if (__predict_false(ncp == NULL)) { |
| 5008 | return (cache_fplookup_noentry(fpl)); |
| 5009 | } |
| 5010 | |
| 5011 | tvp = atomic_load_ptr(&ncp->nc_vp); |
| 5012 | nc_flag = atomic_load_char(&ncp->nc_flag); |
| 5013 | if ((nc_flag & NCF_NEGATIVE) != 0) { |
| 5014 | return (cache_fplookup_neg(fpl, ncp, hash)); |
| 5015 | } |
| 5016 | |
| 5017 | if (!cache_ncp_canuse(ncp)) { |
| 5018 | return (cache_fpl_partial(fpl)); |
| 5019 | } |
| 5020 | |
| 5021 | fpl->tvp = tvp; |
| 5022 | fpl->tvp_seqc = vn_seqc_read_any(tvp); |
| 5023 | if (seqc_in_modify(fpl->tvp_seqc)) { |
| 5024 | return (cache_fpl_partial(fpl)); |
| 5025 | } |
| 5026 | |
| 5027 | counter_u64_add(numposhits, 1); |
| 5028 | SDT_PROBE3(vfs, namecache, lookup, hit, dvp, ncp->nc_name, tvp); |
| 5029 | |
| 5030 | error = 0; |
| 5031 | if (cache_fplookup_is_mp(fpl)) { |
| 5032 | error = cache_fplookup_cross_mount(fpl); |
| 5033 | } |
no test coverage detected