|
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 477-482
fuse_internal_invalidate_inode(struct mount *mp, struct uio *uio)
Link Here
|
| 477 |
*/ |
523 |
*/ |
| 478 |
if (fniio.off >= 0) |
524 |
if (fniio.off >= 0) |
| 479 |
fuse_io_invalbuf(vp, curthread); |
525 |
fuse_io_invalbuf(vp, curthread); |
|
|
526 |
/* TODO: suppress "cache invalid" warning when this happens */ |
| 480 |
fuse_vnode_clear_attr_cache(vp); |
527 |
fuse_vnode_clear_attr_cache(vp); |
| 481 |
vput(vp); |
528 |
vput(vp); |
| 482 |
return (0); |
529 |
return (0); |
|
Lines 806-812
fuse_internal_newentry_core(struct vnode *dvp,
Link Here
|
| 806 |
fuse_vnode_clear_attr_cache(dvp); |
853 |
fuse_vnode_clear_attr_cache(dvp); |
| 807 |
|
854 |
|
| 808 |
fuse_internal_cache_attrs(*vpp, &feo->attr, feo->attr_valid, |
855 |
fuse_internal_cache_attrs(*vpp, &feo->attr, feo->attr_valid, |
| 809 |
feo->attr_valid_nsec, NULL); |
856 |
feo->attr_valid_nsec, NULL, true); |
| 810 |
|
857 |
|
| 811 |
return err; |
858 |
return err; |
| 812 |
} |
859 |
} |
|
Lines 912-937
fuse_internal_do_getattr(struct vnode *vp, struct vattr *vap,
Link Here
|
| 912 |
fao->attr.mtime = old_mtime.tv_sec; |
959 |
fao->attr.mtime = old_mtime.tv_sec; |
| 913 |
fao->attr.mtimensec = old_mtime.tv_nsec; |
960 |
fao->attr.mtimensec = old_mtime.tv_nsec; |
| 914 |
} |
961 |
} |
| 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, |
962 |
fuse_internal_cache_attrs(vp, &fao->attr, fao->attr_valid, |
| 934 |
fao->attr_valid_nsec, vap); |
963 |
fao->attr_valid_nsec, vap, true); |
| 935 |
if (vtyp != vnode_vtype(vp)) { |
964 |
if (vtyp != vnode_vtype(vp)) { |
| 936 |
fuse_internal_vnode_disappear(vp); |
965 |
fuse_internal_vnode_disappear(vp); |
| 937 |
err = ENOENT; |
966 |
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; |
1260 |
struct fuse_attr_out *fao = (struct fuse_attr_out*)fdi.answ; |
| 1232 |
fuse_vnode_undirty_cached_timestamps(vp); |
1261 |
fuse_vnode_undirty_cached_timestamps(vp); |
| 1233 |
fuse_internal_cache_attrs(vp, &fao->attr, fao->attr_valid, |
1262 |
fuse_internal_cache_attrs(vp, &fao->attr, fao->attr_valid, |
| 1234 |
fao->attr_valid_nsec, NULL); |
1263 |
fao->attr_valid_nsec, NULL, false); |
| 1235 |
} |
1264 |
} |
| 1236 |
|
1265 |
|
| 1237 |
out: |
1266 |
out: |