summaryrefslogtreecommitdiffstats
path: root/sys/fs/fuse/fuse_vnops.c
diff options
context:
space:
mode:
authorattilio <attilio@FreeBSD.org>2012-11-08 00:32:49 +0000
committerattilio <attilio@FreeBSD.org>2012-11-08 00:32:49 +0000
commit1e93fc5eebeddeb9b55367b7dbe1cfd50b731fbe (patch)
treed1e3110effbc60ea33841aa63c836e4e9dfbb12f /sys/fs/fuse/fuse_vnops.c
parenta60f06157e6e44ea0691467709b746037e6111c2 (diff)
downloadFreeBSD-src-1e93fc5eebeddeb9b55367b7dbe1cfd50b731fbe.zip
FreeBSD-src-1e93fc5eebeddeb9b55367b7dbe1cfd50b731fbe.tar.gz
- Current caching mode is completely broken because it simply relies
on timing of the operations and not real lookup, bringing too many false positives. Remove the whole mechanism. If it needs to be implemented, next time it should really be done in the proper way. - Fix VOP_GETATTR() in order to cope with userland bugs that would change the type of file and not panic. Instead it gets the entry as if it is not existing. Reported and tested by: flo MFC after: 2 months X-MFC: 241519, 242536,242616
Diffstat (limited to 'sys/fs/fuse/fuse_vnops.c')
-rw-r--r--sys/fs/fuse/fuse_vnops.c57
1 files changed, 12 insertions, 45 deletions
diff --git a/sys/fs/fuse/fuse_vnops.c b/sys/fs/fuse/fuse_vnops.c
index 1774e0a..cc9733d 100644
--- a/sys/fs/fuse/fuse_vnops.c
+++ b/sys/fs/fuse/fuse_vnops.c
@@ -482,17 +482,6 @@ fuse_vnop_getattr(struct vop_getattr_args *ap)
/* Note that we are not bailing out on a dead file system just yet. */
- /* look for cached attributes */
- if (fuse_isvalid_attr(vp)) {
- if (vap != VTOVA(vp)) {
- memcpy(vap, VTOVA(vp), sizeof(*vap));
- }
- if ((fvdat->flag & FN_SIZECHANGE) != 0) {
- vap->va_size = fvdat->filesize;
- }
- debug_printf("return cached: inode=%ju\n", (uintmax_t)VTOI(vp));
- return 0;
- }
if (!(dataflags & FSESS_INITED)) {
if (!vnode_isvroot(vp)) {
fdata_set_dead(fuse_get_mpdata(vnode_mount(vp)));
@@ -519,6 +508,11 @@ fuse_vnop_getattr(struct vop_getattr_args *ap)
if (vap != VTOVA(vp)) {
memcpy(vap, VTOVA(vp), sizeof(*vap));
}
+ if (vap->va_type != vnode_vtype(vp)) {
+ fuse_internal_vnode_disappear(vp);
+ err = ENOENT;
+ goto out;
+ }
if ((fvdat->flag & FN_SIZECHANGE) != 0)
vap->va_size = fvdat->filesize;
@@ -534,7 +528,6 @@ fuse_vnop_getattr(struct vop_getattr_args *ap)
fuse_vnode_setsize(vp, cred, new_filesize);
}
}
- KASSERT(vnode_vtype(vp) == vap->va_type, ("stale vnode"));
debug_printf("fuse_getattr e: returning 0\n");
out:
@@ -635,9 +628,6 @@ fuse_vnop_link(struct vop_link_args *ap)
feo = fdi.answ;
err = fuse_internal_checkentry(feo, vnode_vtype(vp));
- fuse_invalidate_attr(tdvp);
- fuse_invalidate_attr(vp);
-
out:
fdisp_destroy(&fdi);
return err;
@@ -1085,8 +1075,6 @@ fuse_vnop_mkdir(struct vop_mkdir_args *ap)
struct componentname *cnp = ap->a_cnp;
struct vattr *vap = ap->a_vap;
- int err = 0;
-
struct fuse_mkdir_in fmdi;
fuse_trace_printf_vnop();
@@ -1096,13 +1084,8 @@ fuse_vnop_mkdir(struct vop_mkdir_args *ap)
}
fmdi.mode = MAKEIMODE(vap->va_type, vap->va_mode);
- err = fuse_internal_newentry(dvp, vpp, cnp, FUSE_MKDIR, &fmdi,
- sizeof(fmdi), VDIR);
-
- if (err == 0) {
- fuse_invalidate_attr(dvp);
- }
- return err;
+ return (fuse_internal_newentry(dvp, vpp, cnp, FUSE_MKDIR, &fmdi,
+ sizeof(fmdi), VDIR));
}
/*
@@ -1367,10 +1350,8 @@ fuse_vnop_remove(struct vop_remove_args *ap)
err = fuse_internal_remove(dvp, vp, cnp, FUSE_UNLINK);
- if (err == 0) {
+ if (err == 0)
fuse_internal_vnode_disappear(vp);
- fuse_invalidate_attr(dvp);
- }
return err;
}
@@ -1423,11 +1404,8 @@ fuse_vnop_rename(struct vop_rename_args *ap)
sx_xlock(&data->rename_lock);
err = fuse_internal_rename(fdvp, fcnp, tdvp, tcnp);
if (err == 0) {
- fuse_invalidate_attr(fdvp);
- if (tdvp != fdvp) {
+ if (tdvp != fdvp)
fuse_vnode_setparent(fvp, tdvp);
- fuse_invalidate_attr(tdvp);
- }
if (tvp != NULL)
fuse_vnode_setparent(tvp, NULL);
}
@@ -1482,10 +1460,8 @@ fuse_vnop_rmdir(struct vop_rmdir_args *ap)
}
err = fuse_internal_remove(dvp, vp, ap->a_cnp, FUSE_RMDIR);
- if (err == 0) {
+ if (err == 0)
fuse_internal_vnode_disappear(vp);
- fuse_invalidate_attr(dvp);
- }
return err;
}
@@ -1593,14 +1569,10 @@ fuse_vnop_setattr(struct vop_setattr_args *ap)
vap->va_vaflags & VA_UTIMES_NULL) {
err = fuse_internal_access(vp, VWRITE, &facp, td, cred);
}
- if (err) {
- fuse_invalidate_attr(vp);
+ if (err)
goto out;
- }
- if ((err = fdisp_wait_answ(&fdi))) {
- fuse_invalidate_attr(vp);
+ if ((err = fdisp_wait_answ(&fdi)))
goto out;
- }
vtyp = IFTOVT(((struct fuse_attr_out *)fdi.answ)->attr.mode);
if (vnode_vtype(vp) != vtyp) {
@@ -1624,7 +1596,6 @@ fuse_vnop_setattr(struct vop_setattr_args *ap)
out:
fdisp_destroy(&fdi);
if (!err && sizechanged) {
- fuse_invalidate_attr(vp);
fuse_vnode_setsize(vp, cred, newsize);
VTOFUD(vp)->flag &= ~FN_SIZECHANGE;
}
@@ -1715,10 +1686,6 @@ fuse_vnop_symlink(struct vop_symlink_args *ap)
err = fuse_internal_newentry_core(dvp, vpp, cnp, VLNK, &fdi);
fdisp_destroy(&fdi);
-
- if (err == 0) {
- fuse_invalidate_attr(dvp);
- }
return err;
}
OpenPOWER on IntegriCloud