Changeset View
Changeset View
Standalone View
Standalone View
sys/fs/fuse/fuse_internal.c
Show First 20 Lines • Show All 851 Lines • ▼ Show 20 Lines | fuse_internal_forget_send(struct mount *mp, | ||||
ffi = fdi.indata; | ffi = fdi.indata; | ||||
ffi->nlookup = nlookup; | ffi->nlookup = nlookup; | ||||
fuse_insert_message(fdi.tick, false); | fuse_insert_message(fdi.tick, false); | ||||
fdisp_destroy(&fdi); | fdisp_destroy(&fdi); | ||||
} | } | ||||
SDT_PROBE_DEFINE2(fusefs, , internal, getattr_cache_incoherent, | |||||
"struct vnode*", "struct fuse_attr_out*"); | |||||
/* Fetch the vnode's attributes from the daemon*/ | /* Fetch the vnode's attributes from the daemon*/ | ||||
int | int | ||||
fuse_internal_do_getattr(struct vnode *vp, struct vattr *vap, | fuse_internal_do_getattr(struct vnode *vp, struct vattr *vap, | ||||
struct ucred *cred, struct thread *td) | struct ucred *cred, struct thread *td) | ||||
{ | { | ||||
struct fuse_dispatcher fdi; | struct fuse_dispatcher fdi; | ||||
struct fuse_vnode_data *fvdat = VTOFUD(vp); | struct fuse_vnode_data *fvdat = VTOFUD(vp); | ||||
struct fuse_getattr_in *fgai; | struct fuse_getattr_in *fgai; | ||||
Show All 25 Lines | if (fvdat->flag & FN_SIZECHANGE) | ||||
fao->attr.size = old_filesize; | fao->attr.size = old_filesize; | ||||
if (fvdat->flag & FN_CTIMECHANGE) { | if (fvdat->flag & FN_CTIMECHANGE) { | ||||
fao->attr.ctime = old_ctime.tv_sec; | fao->attr.ctime = old_ctime.tv_sec; | ||||
fao->attr.ctimensec = old_ctime.tv_nsec; | fao->attr.ctimensec = old_ctime.tv_nsec; | ||||
} | } | ||||
if (fvdat->flag & FN_MTIMECHANGE) { | if (fvdat->flag & FN_MTIMECHANGE) { | ||||
fao->attr.mtime = old_mtime.tv_sec; | fao->attr.mtime = old_mtime.tv_sec; | ||||
fao->attr.mtimensec = old_mtime.tv_nsec; | fao->attr.mtimensec = old_mtime.tv_nsec; | ||||
} | |||||
if (vnode_isreg(vp) && | |||||
fvdat->cached_attrs.va_size != VNOVAL && | |||||
fao->attr.size != fvdat->cached_attrs.va_size) { | |||||
/* | |||||
* The server changed the file's size even though we had it | |||||
* cached! That's a server bug. | |||||
*/ | |||||
SDT_PROBE2(fusefs, , internal, getattr_cache_incoherent, vp, | |||||
fao); | |||||
printf("%s: cache incoherent on %s! " | |||||
cem: I would probably be even more explicit "this fuse fileserver is buggy and must be mounted with… | |||||
"Buggy FUSE server detected. To prevent data corruption, " | |||||
"disable the data cache by mounting with -o direct_io, or " | |||||
"as directed otherwise by your FUSE server's " | |||||
"documentation\n", __func__, | |||||
vnode_mount(vp)->mnt_stat.f_mntonname); | |||||
int iosize = fuse_iosize(vp); | |||||
v_inval_buf_range(vp, 0, INT64_MAX, iosize); | |||||
} | } | ||||
fuse_internal_cache_attrs(vp, &fao->attr, fao->attr_valid, | fuse_internal_cache_attrs(vp, &fao->attr, fao->attr_valid, | ||||
fao->attr_valid_nsec, vap); | fao->attr_valid_nsec, vap); | ||||
if (vtyp != vnode_vtype(vp)) { | if (vtyp != vnode_vtype(vp)) { | ||||
fuse_internal_vnode_disappear(vp); | fuse_internal_vnode_disappear(vp); | ||||
err = ENOENT; | err = ENOENT; | ||||
} | } | ||||
▲ Show 20 Lines • Show All 312 Lines • Show Last 20 Lines |
I would probably be even more explicit "this fuse fileserver is buggy and must be mounted with -o direct_io" or something like that. We're very much papering over possible corruption here and it is easy for it to go undetected if a file is not extended or truncated.