Changeset View
Changeset View
Standalone View
Standalone View
sys/kern/vfs_cache.c
Show First 20 Lines • Show All 3,670 Lines • ▼ Show 20 Lines | vn_fullpath_hardlink(struct vnode *vp, struct vnode *dvp, | ||||
* For example consider tmpfs on /tmp and realpath /tmp. ni_vp will be | * For example consider tmpfs on /tmp and realpath /tmp. ni_vp will be | ||||
* set to mount point's root vnode while ni_dvp will be vp_crossmp. | * set to mount point's root vnode while ni_dvp will be vp_crossmp. | ||||
* If the type is VDIR (like in this very case) we can skip looking | * If the type is VDIR (like in this very case) we can skip looking | ||||
* at ni_dvp in the first place. However, since vnodes get passed here | * at ni_dvp in the first place. However, since vnodes get passed here | ||||
* unlocked the target may transition to doomed state (type == VBAD) | * unlocked the target may transition to doomed state (type == VBAD) | ||||
* before we get to evaluate the condition. If this happens, we will | * before we get to evaluate the condition. If this happens, we will | ||||
* populate part of the buffer and descend to vn_fullpath_dir with | * populate part of the buffer and descend to vn_fullpath_dir with | ||||
* vp == vp_crossmp. Prevent the problem by checking for VBAD. | * vp == vp_crossmp. Prevent the problem by checking for VBAD. | ||||
* | |||||
* This should be atomic_load(&vp->v_type) but it is illegal to take | |||||
* an address of a bit field, even if said field is sized to char. | |||||
* Work around the problem by reading the value into a full-sized enum | |||||
* and then re-reading it with atomic_load which will still prevent | |||||
* the compiler from re-reading down the road. | |||||
*/ | */ | ||||
type = vp->v_type; | type = atomic_load_char(&type); | ||||
mjg: i think it is time for atomic_load which figures out the size btw | |||||
kibUnsubmitted Not Done Inline ActionsOr, for the sake of this commit, add atomic_load_enum_uint8 kib: Or, for the sake of this commit, add `atomic_load_enum_uint8` | |||||
type = atomic_load_int(&type); | |||||
if (type == VBAD) { | if (type == VBAD) { | ||||
error = ENOENT; | error = ENOENT; | ||||
goto out_bad; | goto out_bad; | ||||
} | } | ||||
if (type != VDIR) { | if (type != VDIR) { | ||||
addend = hrdl_name_length + 2; | addend = hrdl_name_length + 2; | ||||
if (*buflen < addend) { | if (*buflen < addend) { | ||||
error = ENOMEM; | error = ENOMEM; | ||||
▲ Show 20 Lines • Show All 2,506 Lines • Show Last 20 Lines |
i think it is time for atomic_load which figures out the size btw