Lines 255-261
fuse_internal_access(struct vnode *vp,
Link Here
|
255 |
*/ |
255 |
*/ |
256 |
void |
256 |
void |
257 |
fuse_internal_cache_attrs(struct vnode *vp, struct fuse_attr *attr, |
257 |
fuse_internal_cache_attrs(struct vnode *vp, struct fuse_attr *attr, |
258 |
uint64_t attr_valid, uint32_t attr_valid_nsec, struct vattr *vap) |
258 |
uint64_t attr_valid, uint32_t attr_valid_nsec, struct vattr *vap, |
|
|
259 |
bool from_server) |
259 |
{ |
260 |
{ |
260 |
struct mount *mp; |
261 |
struct mount *mp; |
261 |
struct fuse_vnode_data *fvdat; |
262 |
struct fuse_vnode_data *fvdat; |
Lines 271-279
fuse_internal_cache_attrs(struct vnode *vp, struct fuse_attr *attr,
Link Here
|
271 |
fuse_validity_2_bintime(attr_valid, attr_valid_nsec, |
272 |
fuse_validity_2_bintime(attr_valid, attr_valid_nsec, |
272 |
&fvdat->attr_cache_timeout); |
273 |
&fvdat->attr_cache_timeout); |
273 |
|
274 |
|
|
|
275 |
if (vnode_isreg(vp) && |
276 |
fvdat->cached_attrs.va_size != VNOVAL && |
277 |
attr->size != fvdat->cached_attrs.va_size) |
278 |
{ |
279 |
if ( data->cache_mode == FUSE_CACHE_WB && |
280 |
fvdat->flag & FN_SIZECHANGE) |
281 |
{ |
282 |
const char *msg; |
283 |
|
284 |
/* |
285 |
* The server changed the file's size even though we're |
286 |
* using writeback cacheing and and we have outstanding |
287 |
* dirty writes! That's a server bug. |
288 |
*/ |
289 |
if (fuse_libabi_geq(data, 7, 23)) { |
290 |
msg = "writeback cache incoherent!." |
291 |
"To prevent data corruption, disable " |
292 |
"the writeback cache according to your " |
293 |
"FUSE server's documentation."; |
294 |
} else { |
295 |
msg = "writeback cache incoherent!." |
296 |
"To prevent data corruption, disable " |
297 |
"the writeback cache by setting " |
298 |
"vfs.fusefs.data_cache_mode to 0 or 1."; |
299 |
} |
300 |
fuse_warn(data, FSESS_WARN_WB_CACHE_INCOHERENT, msg); |
301 |
} |
302 |
if (fuse_vnode_attr_cache_valid(vp) && |
303 |
data->cache_mode != FUSE_CACHE_UC) |
304 |
{ |
305 |
/* |
306 |
* The server changed the file's size even though we |
307 |
* have it cached and our cache has not yet expired. |
308 |
* That's a bug. |
309 |
*/ |
310 |
fuse_warn(data, FSESS_WARN_CACHE_INCOHERENT, |
311 |
"cache incoherent! " |
312 |
"To prevent " |
313 |
"data corruption, disable the data cache " |
314 |
"by mounting with -o direct_io, or as " |
315 |
"directed otherwise by your FUSE server's " |
316 |
"documentation."); |
317 |
} |
318 |
} |
319 |
|
274 |
/* Fix our buffers if the filesize changed without us knowing */ |
320 |
/* Fix our buffers if the filesize changed without us knowing */ |
275 |
if (vnode_isreg(vp) && attr->size != fvdat->cached_attrs.va_size) { |
321 |
if (vnode_isreg(vp) && attr->size != fvdat->cached_attrs.va_size) { |
276 |
(void)fuse_vnode_setsize(vp, attr->size); |
322 |
(void)fuse_vnode_setsize(vp, attr->size, from_server); |
277 |
fvdat->cached_attrs.va_size = attr->size; |
323 |
fvdat->cached_attrs.va_size = attr->size; |
278 |
} |
324 |
} |
279 |
|
325 |
|
Lines 806-812
fuse_internal_newentry_core(struct vnode *dvp,
Link Here
|
806 |
fuse_vnode_clear_attr_cache(dvp); |
852 |
fuse_vnode_clear_attr_cache(dvp); |
807 |
|
853 |
|
808 |
fuse_internal_cache_attrs(*vpp, &feo->attr, feo->attr_valid, |
854 |
fuse_internal_cache_attrs(*vpp, &feo->attr, feo->attr_valid, |
809 |
feo->attr_valid_nsec, NULL); |
855 |
feo->attr_valid_nsec, NULL, true); |
810 |
|
856 |
|
811 |
return err; |
857 |
return err; |
812 |
} |
858 |
} |
Lines 912-937
fuse_internal_do_getattr(struct vnode *vp, struct vattr *vap,
Link Here
|
912 |
fao->attr.mtime = old_mtime.tv_sec; |
958 |
fao->attr.mtime = old_mtime.tv_sec; |
913 |
fao->attr.mtimensec = old_mtime.tv_nsec; |
959 |
fao->attr.mtimensec = old_mtime.tv_nsec; |
914 |
} |
960 |
} |
915 |
if (vnode_isreg(vp) && |
|
|
916 |
fvdat->cached_attrs.va_size != VNOVAL && |
917 |
fao->attr.size != fvdat->cached_attrs.va_size) { |
918 |
/* |
919 |
* The server changed the file's size even though we had it |
920 |
* cached! That's a server bug. |
921 |
*/ |
922 |
struct mount *mp = vnode_mount(vp); |
923 |
struct fuse_data *data = fuse_get_mpdata(mp); |
924 |
|
925 |
fuse_warn(data, FSESS_WARN_CACHE_INCOHERENT, |
926 |
"cache incoherent! " |
927 |
"To prevent data corruption, disable the data cache " |
928 |
"by mounting with -o direct_io, or as directed " |
929 |
"otherwise by your FUSE server's documentation."); |
930 |
int iosize = fuse_iosize(vp); |
931 |
v_inval_buf_range(vp, 0, INT64_MAX, iosize); |
932 |
} |
933 |
fuse_internal_cache_attrs(vp, &fao->attr, fao->attr_valid, |
961 |
fuse_internal_cache_attrs(vp, &fao->attr, fao->attr_valid, |
934 |
fao->attr_valid_nsec, vap); |
962 |
fao->attr_valid_nsec, vap, true); |
935 |
if (vtyp != vnode_vtype(vp)) { |
963 |
if (vtyp != vnode_vtype(vp)) { |
936 |
fuse_internal_vnode_disappear(vp); |
964 |
fuse_internal_vnode_disappear(vp); |
937 |
err = ENOENT; |
965 |
err = ENOENT; |
Lines 1231-1237
int fuse_internal_setattr(struct vnode *vp, struct vattr *vap,
Link Here
|
1231 |
struct fuse_attr_out *fao = (struct fuse_attr_out*)fdi.answ; |
1259 |
struct fuse_attr_out *fao = (struct fuse_attr_out*)fdi.answ; |
1232 |
fuse_vnode_undirty_cached_timestamps(vp); |
1260 |
fuse_vnode_undirty_cached_timestamps(vp); |
1233 |
fuse_internal_cache_attrs(vp, &fao->attr, fao->attr_valid, |
1261 |
fuse_internal_cache_attrs(vp, &fao->attr, fao->attr_valid, |
1234 |
fao->attr_valid_nsec, NULL); |
1262 |
fao->attr_valid_nsec, NULL, false); |
1235 |
} |
1263 |
} |
1236 |
|
1264 |
|
1237 |
out: |
1265 |
out: |