* They want to possibly modify the state of the namecache. */
| 4200 | * They want to possibly modify the state of the namecache. |
| 4201 | */ |
| 4202 | static int __noinline |
| 4203 | cache_fplookup_final_modifying(struct cache_fpl *fpl) |
| 4204 | { |
| 4205 | struct nameidata *ndp; |
| 4206 | struct componentname *cnp; |
| 4207 | enum vgetstate dvs; |
| 4208 | struct vnode *dvp, *tvp; |
| 4209 | struct mount *mp; |
| 4210 | seqc_t dvp_seqc; |
| 4211 | int error; |
| 4212 | bool docache; |
| 4213 | |
| 4214 | ndp = fpl->ndp; |
| 4215 | cnp = fpl->cnp; |
| 4216 | dvp = fpl->dvp; |
| 4217 | dvp_seqc = fpl->dvp_seqc; |
| 4218 | |
| 4219 | MPASS(*(cnp->cn_nameptr) != '/'); |
| 4220 | MPASS(cache_fpl_islastcn(ndp)); |
| 4221 | if ((cnp->cn_flags & LOCKPARENT) == 0) |
| 4222 | MPASS((cnp->cn_flags & WANTPARENT) != 0); |
| 4223 | MPASS((cnp->cn_flags & TRAILINGSLASH) == 0); |
| 4224 | MPASS(cnp->cn_nameiop == CREATE || cnp->cn_nameiop == DELETE || |
| 4225 | cnp->cn_nameiop == RENAME); |
| 4226 | MPASS((cnp->cn_flags & MAKEENTRY) == 0); |
| 4227 | MPASS((cnp->cn_flags & ISDOTDOT) == 0); |
| 4228 | |
| 4229 | docache = (cnp->cn_flags & NOCACHE) ^ NOCACHE; |
| 4230 | if (cnp->cn_nameiop == DELETE || cnp->cn_nameiop == RENAME) |
| 4231 | docache = false; |
| 4232 | |
| 4233 | /* |
| 4234 | * Regular lookup nulifies the slash, which we don't do here. |
| 4235 | * Don't take chances with filesystem routines seeing it for |
| 4236 | * the last entry. |
| 4237 | */ |
| 4238 | if (cache_fpl_istrailingslash(fpl)) { |
| 4239 | return (cache_fpl_partial(fpl)); |
| 4240 | } |
| 4241 | |
| 4242 | mp = atomic_load_ptr(&dvp->v_mount); |
| 4243 | if (__predict_false(mp == NULL)) { |
| 4244 | return (cache_fpl_aborted(fpl)); |
| 4245 | } |
| 4246 | |
| 4247 | if (__predict_false(mp->mnt_flag & MNT_RDONLY)) { |
| 4248 | cache_fpl_smr_exit(fpl); |
| 4249 | /* |
| 4250 | * Original code keeps not checking for CREATE which |
| 4251 | * might be a bug. For now let the old lookup decide. |
| 4252 | */ |
| 4253 | if (cnp->cn_nameiop == CREATE) { |
| 4254 | return (cache_fpl_aborted(fpl)); |
| 4255 | } |
| 4256 | return (cache_fpl_handled_error(fpl, EROFS)); |
| 4257 | } |
| 4258 | |
| 4259 | if (fpl->tvp != NULL && (cnp->cn_flags & FAILIFEXISTS) != 0) { |
no test coverage detected