Changeset View
Changeset View
Standalone View
Standalone View
sys/fs/fuse/fuse_vfsops.c
Show First 20 Lines • Show All 570 Lines • ▼ Show 20 Lines | if (feo->nodeid == 0) { | ||||
error = ENOENT; | error = ENOENT; | ||||
goto out; | goto out; | ||||
} | } | ||||
vtyp = IFTOVT(feo->attr.mode); | vtyp = IFTOVT(feo->attr.mode); | ||||
error = fuse_vnode_get(mp, feo, nodeid, NULL, vpp, NULL, vtyp); | error = fuse_vnode_get(mp, feo, nodeid, NULL, vpp, NULL, vtyp); | ||||
if (error) | if (error) | ||||
goto out; | goto out; | ||||
ASSERT_VOP_ELOCKED(*vpp, __func__); | |||||
filesize = feo->attr.size; | filesize = feo->attr.size; | ||||
/* | /* | ||||
* In the case where we are looking up a FUSE node represented by an | * In the case where we are looking up a FUSE node represented by an | ||||
* existing cached vnode, and the true size reported by FUSE_LOOKUP | * existing cached vnode, and the true size reported by FUSE_LOOKUP | ||||
* doesn't match the vnode's cached size, then any cached writes beyond | * doesn't match the vnode's cached size, then any cached writes beyond | ||||
* the file's current size are lost. | * the file's current size are lost. | ||||
* | * | ||||
* We can get here: | * We can get here: | ||||
* * following attribute cache expiration, or | * * following attribute cache expiration, or | ||||
* * due a bug in the daemon, or | * * due a bug in the daemon, or | ||||
*/ | */ | ||||
fvdat = VTOFUD(*vpp); | fvdat = VTOFUD(*vpp); | ||||
if (vnode_isreg(*vpp) && | if (vnode_isreg(*vpp) && | ||||
filesize != fvdat->cached_attrs.va_size && | filesize != fvdat->cached_attrs.va_size && | ||||
fvdat->flag & FN_SIZECHANGE) { | fvdat->flag & FN_SIZECHANGE) { | ||||
printf("%s: WB cache incoherent on %s!\n", __func__, | printf("%s: WB cache incoherent on %s!\n", __func__, | ||||
vnode_mount(*vpp)->mnt_stat.f_mntonname); | vnode_mount(*vpp)->mnt_stat.f_mntonname); | ||||
fvdat->flag &= ~FN_SIZECHANGE; | fvdat->flag &= ~FN_SIZECHANGE; | ||||
cem: We can update `flag` non-atomically with only a shared lock? (Probably not, I think we need… | |||||
Done Inline ActionsThat's also part of v_data. I'll audit that later. asomers: That's also part of v_data. I'll audit that later. | |||||
} | } | ||||
fuse_internal_cache_attrs(*vpp, &feo->attr, feo->attr_valid, | fuse_internal_cache_attrs(*vpp, &feo->attr, feo->attr_valid, | ||||
feo->attr_valid_nsec, NULL); | feo->attr_valid_nsec, NULL); | ||||
fuse_validity_2_bintime(feo->entry_valid, feo->entry_valid_nsec, | fuse_validity_2_bintime(feo->entry_valid, feo->entry_valid_nsec, | ||||
&fvdat->entry_cache_timeout); | &fvdat->entry_cache_timeout); | ||||
Done Inline ActionsThese need ELOCK. That vnode is visible on the mount hash/queue concurrent threads before fuse_vnode_get() returns. cem: These need ELOCK. That vnode is visible on the mount hash/queue concurrent threads before… | |||||
Done Inline ActionsWe'll have ELOCK here, because fuse_vnode_get returns an exclusively locked vnode. asomers: We'll have ELOCK here, because `fuse_vnode_get` returns an exclusively locked vnode. | |||||
Done Inline ActionsThen we can should ASSERT_VOP_ELOCKED rather than VOP_LOCKED ... cem: Then we can should ASSERT_VOP_ELOCKED rather than VOP_LOCKED ... | |||||
out: | out: | ||||
fdisp_destroy(&fdi); | fdisp_destroy(&fdi); | ||||
return error; | return error; | ||||
} | } | ||||
static int | static int | ||||
fuse_vfsop_root(struct mount *mp, int lkflags, struct vnode **vpp) | fuse_vfsop_root(struct mount *mp, int lkflags, struct vnode **vpp) | ||||
{ | { | ||||
▲ Show 20 Lines • Show All 87 Lines • Show Last 20 Lines |
We can update flag non-atomically with only a shared lock? (Probably not, I think we need ELOCK or significant rototill of flags access.)