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

Function cache_neg_promote_cond

freebsd/kern/vfs_cache.c:1184–1252  ·  view source on GitHub ↗

* Move a negative entry to the hot list if it matches the lookup. * * We have to take locks, but they may be contended and in the worst * case we may need to go off CPU. We don't want to spin within the * smr section and we can't block with it. Exiting the section means * the found entry could have been evicted. We are going to look it * up again. */

Source from the content-addressed store, hash-verified

1182 * up again.
1183 */
1184static bool
1185cache_neg_promote_cond(struct vnode *dvp, struct componentname *cnp,
1186 struct namecache *oncp, uint32_t hash)
1187{
1188 struct namecache *ncp;
1189 struct neglist *nl;
1190 u_char nc_flag;
1191
1192 nl = NCP2NEGLIST(oncp);
1193
1194 mtx_lock(&nl->nl_lock);
1195 /*
1196 * For hash iteration.
1197 */
1198 vfs_smr_enter();
1199
1200 /*
1201 * Avoid all surprises by only succeeding if we got the same entry and
1202 * bailing completely otherwise.
1203 * XXX There are no provisions to keep the vnode around, meaning we may
1204 * end up promoting a negative entry for a *new* vnode and returning
1205 * ENOENT on its account. This is the error we want to return anyway
1206 * and promotion is harmless.
1207 *
1208 * In particular at this point there can be a new ncp which matches the
1209 * search but hashes to a different neglist.
1210 */
1211 CK_SLIST_FOREACH(ncp, (NCHHASH(hash)), nc_hash) {
1212 if (ncp == oncp)
1213 break;
1214 }
1215
1216 /*
1217 * No match to begin with.
1218 */
1219 if (__predict_false(ncp == NULL)) {
1220 goto out_abort;
1221 }
1222
1223 /*
1224 * The newly found entry may be something different...
1225 */
1226 if (!(ncp->nc_dvp == dvp && ncp->nc_nlen == cnp->cn_namelen &&
1227 !bcmp(ncp->nc_name, cnp->cn_nameptr, ncp->nc_nlen))) {
1228 goto out_abort;
1229 }
1230
1231 /*
1232 * ... and not even negative.
1233 */
1234 nc_flag = atomic_load_char(&ncp->nc_flag);
1235 if ((nc_flag & NCF_NEGATIVE) == 0) {
1236 goto out_abort;
1237 }
1238
1239 if (!cache_ncp_canuse(ncp)) {
1240 goto out_abort;
1241 }

Callers 2

cache_lookupFunction · 0.85

Calls 5

NCP2NEGLISTFunction · 0.85
cache_neg_promote_lockedFunction · 0.85
cache_neg_hit_finishFunction · 0.85
mtx_lockFunction · 0.70
mtx_unlockFunction · 0.70

Tested by

no test coverage detected