| 4162 | } |
| 4163 | |
| 4164 | static int |
| 4165 | cache_fplookup_final_child(struct cache_fpl *fpl, enum vgetstate tvs) |
| 4166 | { |
| 4167 | struct componentname *cnp; |
| 4168 | struct vnode *tvp; |
| 4169 | seqc_t tvp_seqc; |
| 4170 | int error, lkflags; |
| 4171 | |
| 4172 | cnp = fpl->cnp; |
| 4173 | tvp = fpl->tvp; |
| 4174 | tvp_seqc = fpl->tvp_seqc; |
| 4175 | |
| 4176 | if ((cnp->cn_flags & LOCKLEAF) != 0) { |
| 4177 | lkflags = LK_SHARED; |
| 4178 | if ((cnp->cn_flags & LOCKSHARED) == 0) |
| 4179 | lkflags = LK_EXCLUSIVE; |
| 4180 | error = vget_finish(tvp, lkflags, tvs); |
| 4181 | if (__predict_false(error != 0)) { |
| 4182 | return (cache_fpl_aborted(fpl)); |
| 4183 | } |
| 4184 | } else { |
| 4185 | vget_finish_ref(tvp, tvs); |
| 4186 | } |
| 4187 | |
| 4188 | if (!vn_seqc_consistent(tvp, tvp_seqc)) { |
| 4189 | if ((cnp->cn_flags & LOCKLEAF) != 0) |
| 4190 | vput(tvp); |
| 4191 | else |
| 4192 | vrele(tvp); |
| 4193 | return (cache_fpl_aborted(fpl)); |
| 4194 | } |
| 4195 | |
| 4196 | return (cache_fpl_handled(fpl)); |
| 4197 | } |
| 4198 | |
| 4199 | /* |
| 4200 | * They want to possibly modify the state of the namecache. |
no test coverage detected