| 1495 | } |
| 1496 | |
| 1497 | static bool |
| 1498 | cache_zap_locked_vnode_kl2(struct namecache *ncp, struct vnode *vp, |
| 1499 | struct mtx **vlpp) |
| 1500 | { |
| 1501 | struct mtx *pvlp, *vlp1, *vlp2, *to_unlock; |
| 1502 | struct mtx *blp; |
| 1503 | |
| 1504 | MPASS(vp == ncp->nc_dvp || vp == ncp->nc_vp); |
| 1505 | cache_assert_vnode_locked(vp); |
| 1506 | |
| 1507 | if (ncp->nc_flag & NCF_NEGATIVE) { |
| 1508 | if (*vlpp != NULL) { |
| 1509 | mtx_unlock(*vlpp); |
| 1510 | *vlpp = NULL; |
| 1511 | } |
| 1512 | cache_zap_negative_locked_vnode_kl(ncp, vp); |
| 1513 | return (true); |
| 1514 | } |
| 1515 | |
| 1516 | pvlp = VP2VNODELOCK(vp); |
| 1517 | blp = NCP2BUCKETLOCK(ncp); |
| 1518 | vlp1 = VP2VNODELOCK(ncp->nc_dvp); |
| 1519 | vlp2 = VP2VNODELOCK(ncp->nc_vp); |
| 1520 | |
| 1521 | if (*vlpp == vlp1 || *vlpp == vlp2) { |
| 1522 | to_unlock = *vlpp; |
| 1523 | *vlpp = NULL; |
| 1524 | } else { |
| 1525 | if (*vlpp != NULL) { |
| 1526 | mtx_unlock(*vlpp); |
| 1527 | *vlpp = NULL; |
| 1528 | } |
| 1529 | cache_sort_vnodes(&vlp1, &vlp2); |
| 1530 | if (vlp1 == pvlp) { |
| 1531 | mtx_lock(vlp2); |
| 1532 | to_unlock = vlp2; |
| 1533 | } else { |
| 1534 | if (!mtx_trylock(vlp1)) |
| 1535 | goto out_relock; |
| 1536 | to_unlock = vlp1; |
| 1537 | } |
| 1538 | } |
| 1539 | mtx_lock(blp); |
| 1540 | cache_zap_locked(ncp); |
| 1541 | mtx_unlock(blp); |
| 1542 | if (to_unlock != NULL) |
| 1543 | mtx_unlock(to_unlock); |
| 1544 | return (true); |
| 1545 | |
| 1546 | out_relock: |
| 1547 | mtx_unlock(vlp2); |
| 1548 | mtx_lock(vlp1); |
| 1549 | mtx_lock(vlp2); |
| 1550 | MPASS(*vlpp == NULL); |
| 1551 | *vlpp = vlp1; |
| 1552 | return (false); |
| 1553 | } |
| 1554 |
no test coverage detected