| 4469 | } |
| 4470 | |
| 4471 | static int |
| 4472 | cache_fplookup_final(struct cache_fpl *fpl) |
| 4473 | { |
| 4474 | struct componentname *cnp; |
| 4475 | enum vgetstate tvs; |
| 4476 | struct vnode *dvp, *tvp; |
| 4477 | seqc_t dvp_seqc; |
| 4478 | |
| 4479 | cnp = fpl->cnp; |
| 4480 | dvp = fpl->dvp; |
| 4481 | dvp_seqc = fpl->dvp_seqc; |
| 4482 | tvp = fpl->tvp; |
| 4483 | |
| 4484 | MPASS(*(cnp->cn_nameptr) != '/'); |
| 4485 | |
| 4486 | if (cnp->cn_nameiop != LOOKUP) { |
| 4487 | return (cache_fplookup_final_modifying(fpl)); |
| 4488 | } |
| 4489 | |
| 4490 | if ((cnp->cn_flags & (LOCKPARENT|WANTPARENT)) != 0) |
| 4491 | return (cache_fplookup_final_withparent(fpl)); |
| 4492 | |
| 4493 | tvs = vget_prep_smr(tvp); |
| 4494 | if (__predict_false(tvs == VGET_NONE)) { |
| 4495 | return (cache_fpl_partial(fpl)); |
| 4496 | } |
| 4497 | |
| 4498 | if (!vn_seqc_consistent(dvp, dvp_seqc)) { |
| 4499 | cache_fpl_smr_exit(fpl); |
| 4500 | vget_abort(tvp, tvs); |
| 4501 | return (cache_fpl_aborted(fpl)); |
| 4502 | } |
| 4503 | |
| 4504 | cache_fpl_smr_exit(fpl); |
| 4505 | return (cache_fplookup_final_child(fpl, tvs)); |
| 4506 | } |
| 4507 | |
| 4508 | /* |
| 4509 | * Comment from locked lookup: |
no test coverage detected