| 1924 | } |
| 1925 | |
| 1926 | int |
| 1927 | cache_lookup(struct vnode *dvp, struct vnode **vpp, struct componentname *cnp, |
| 1928 | struct timespec *tsp, int *ticksp) |
| 1929 | { |
| 1930 | struct namecache *ncp; |
| 1931 | uint32_t hash; |
| 1932 | enum vgetstate vs; |
| 1933 | int error; |
| 1934 | bool whiteout, neg_promote; |
| 1935 | u_short nc_flag; |
| 1936 | |
| 1937 | MPASS((tsp == NULL && ticksp == NULL) || (tsp != NULL && ticksp != NULL)); |
| 1938 | |
| 1939 | #ifdef DEBUG_CACHE |
| 1940 | if (__predict_false(!doingcache)) { |
| 1941 | cnp->cn_flags &= ~MAKEENTRY; |
| 1942 | return (0); |
| 1943 | } |
| 1944 | #endif |
| 1945 | |
| 1946 | if (__predict_false(cnp->cn_nameptr[0] == '.')) { |
| 1947 | if (cnp->cn_namelen == 1) |
| 1948 | return (cache_lookup_dot(dvp, vpp, cnp, tsp, ticksp)); |
| 1949 | if (cnp->cn_namelen == 2 && cnp->cn_nameptr[1] == '.') |
| 1950 | return (cache_lookup_dotdot(dvp, vpp, cnp, tsp, ticksp)); |
| 1951 | } |
| 1952 | |
| 1953 | MPASS((cnp->cn_flags & ISDOTDOT) == 0); |
| 1954 | |
| 1955 | if ((cnp->cn_flags & (MAKEENTRY | NC_KEEPPOSENTRY)) == 0) { |
| 1956 | cache_remove_cnp(dvp, cnp); |
| 1957 | return (0); |
| 1958 | } |
| 1959 | |
| 1960 | hash = cache_get_hash(cnp->cn_nameptr, cnp->cn_namelen, dvp); |
| 1961 | vfs_smr_enter(); |
| 1962 | |
| 1963 | CK_SLIST_FOREACH(ncp, (NCHHASH(hash)), nc_hash) { |
| 1964 | if (ncp->nc_dvp == dvp && ncp->nc_nlen == cnp->cn_namelen && |
| 1965 | !bcmp(ncp->nc_name, cnp->cn_nameptr, ncp->nc_nlen)) |
| 1966 | break; |
| 1967 | } |
| 1968 | |
| 1969 | if (__predict_false(ncp == NULL)) { |
| 1970 | vfs_smr_exit(); |
| 1971 | SDT_PROBE3(vfs, namecache, lookup, miss, dvp, cnp->cn_nameptr, |
| 1972 | NULL); |
| 1973 | counter_u64_add(nummiss, 1); |
| 1974 | return (0); |
| 1975 | } |
| 1976 | |
| 1977 | nc_flag = atomic_load_char(&ncp->nc_flag); |
| 1978 | if (nc_flag & NCF_NEGATIVE) |
| 1979 | goto negative_success; |
| 1980 | |
| 1981 | counter_u64_add(numposhits, 1); |
| 1982 | *vpp = ncp->nc_vp; |
| 1983 | SDT_PROBE3(vfs, namecache, lookup, hit, dvp, ncp->nc_name, *vpp); |
no test coverage detected