| 3224 | #define cache_rev_failed(var) cache_rev_failed_impl((var), __LINE__) |
| 3225 | |
| 3226 | static int |
| 3227 | vn_fullpath_any_smr(struct vnode *vp, struct vnode *rdir, char *buf, |
| 3228 | char **retbuf, size_t *buflen, size_t addend) |
| 3229 | { |
| 3230 | #ifdef KDTRACE_HOOKS |
| 3231 | struct vnode *startvp = vp; |
| 3232 | #endif |
| 3233 | struct vnode *tvp; |
| 3234 | struct mount *mp; |
| 3235 | struct namecache *ncp; |
| 3236 | size_t orig_buflen; |
| 3237 | int reason; |
| 3238 | int error; |
| 3239 | #ifdef KDTRACE_HOOKS |
| 3240 | int i; |
| 3241 | #endif |
| 3242 | seqc_t vp_seqc, tvp_seqc; |
| 3243 | u_char nc_flag; |
| 3244 | |
| 3245 | VFS_SMR_ASSERT_ENTERED(); |
| 3246 | |
| 3247 | if (!cache_fast_revlookup) { |
| 3248 | vfs_smr_exit(); |
| 3249 | return (-1); |
| 3250 | } |
| 3251 | |
| 3252 | orig_buflen = *buflen; |
| 3253 | |
| 3254 | if (addend == 0) { |
| 3255 | MPASS(*buflen >= 2); |
| 3256 | *buflen -= 1; |
| 3257 | buf[*buflen] = '\0'; |
| 3258 | } |
| 3259 | |
| 3260 | if (vp == rdir || vp == rootvnode) { |
| 3261 | if (addend == 0) { |
| 3262 | *buflen -= 1; |
| 3263 | buf[*buflen] = '/'; |
| 3264 | } |
| 3265 | goto out_ok; |
| 3266 | } |
| 3267 | |
| 3268 | #ifdef KDTRACE_HOOKS |
| 3269 | i = 0; |
| 3270 | #endif |
| 3271 | error = -1; |
| 3272 | ncp = NULL; /* for sdt probe down below */ |
| 3273 | vp_seqc = vn_seqc_read_any(vp); |
| 3274 | if (seqc_in_modify(vp_seqc)) { |
| 3275 | cache_rev_failed(&reason); |
| 3276 | goto out_abort; |
| 3277 | } |
| 3278 | |
| 3279 | for (;;) { |
| 3280 | #ifdef KDTRACE_HOOKS |
| 3281 | i++; |
| 3282 | #endif |
| 3283 | if ((vp->v_vflag & VV_ROOT) != 0) { |
no test coverage detected