-/* $OpenBSD: fuse_vfsops.c,v 1.40 2018/07/05 15:34:25 mpi Exp $ */
+/* $OpenBSD: fuse_vfsops.c,v 1.41 2018/07/16 16:44:09 helg Exp $ */
/*
* Copyright (c) 2012-2013 Sylvestre Gallon <ccna.syl@gmail.com>
*
int
fusefs_vget(struct mount *mp, ino_t ino, struct vnode **vpp)
{
+ struct vattr vattr;
struct fusefs_mnt *fmp;
struct fusefs_node *ip;
struct vnode *nvp;
if (ino == FUSE_ROOTINO)
nvp->v_flag |= VROOT;
+ /*
+ * Initialise the file size so that file size changes can be
+ * detected during file operations.
+ */
+ error = VOP_GETATTR(nvp, &vattr, curproc->p_ucred, curproc);
+ if (error) {
+ vrele(nvp);
+ return (error);
+ }
+ ip->filesize = vattr.va_size;
+
*vpp = nvp;
return (0);
-/* $OpenBSD: fuse_vnops.c,v 1.50 2018/07/16 13:10:53 helg Exp $ */
+/* $OpenBSD: fuse_vnops.c,v 1.51 2018/07/16 16:44:09 helg Exp $ */
/*
* Copyright (c) 2012-2013 Sylvestre Gallon <ccna.syl@gmail.com>
*
struct vop_open_args *ap;
struct fusefs_node *ip;
struct fusefs_mnt *fmp;
+ struct vnode *vp;
enum fufh_type fufh_type = FUFH_RDONLY;
int flags;
int error;
int isdir;
ap = v;
- ip = VTOI(ap->a_vp);
+ vp = ap->a_vp;
+ ip = VTOI(vp);
fmp = (struct fusefs_mnt *)ip->ufs_ino.i_ump;
if (!fmp->sess_init)
return (ENXIO);
isdir = 0;
- if (ap->a_vp->v_type == VDIR)
+ if (vp->v_type == VDIR)
isdir = 1;
else {
if ((ap->a_mode & FREAD) && (ap->a_mode & FWRITE))
fufh_type = FUFH_RDWR;
else if (ap->a_mode & (FWRITE))
fufh_type = FUFH_WRONLY;
+
+ /*
+ * Due to possible attribute caching, there is no
+ * reliable way to determine if the file was modified
+ * externally (e.g. network file system) so clear the
+ * UVM cache to ensure that it is not stale. The file
+ * can still become stale later on read but this will
+ * satisfy most situations.
+ */
+ uvm_vnp_uncache(vp);
}
/* already open i think all is ok */
goto out;
}
+ /* truncate was successful, let uvm know */
+ if (vap->va_size != VNOVAL && vap->va_size != ip->filesize) {
+ ip->filesize = vap->va_size;
+ uvm_vnp_setsize(vp, vap->va_size);
+ }
+
VN_KNOTE(ap->a_vp, NOTE_ATTRIB);
out:
uio->uio_resid += diff;
uio->uio_offset -= diff;
+ if (uio->uio_offset > ip->filesize) {
+ ip->filesize = uio->uio_offset;
+ uvm_vnp_setsize(vp, uio->uio_offset);
+ }
+ uvm_vnp_uncache(vp);
+
fb_delete(fbuf);
fbuf = NULL;
}
-/* $OpenBSD: uvm_vnode.c,v 1.102 2018/05/02 02:24:56 visa Exp $ */
+/* $OpenBSD: uvm_vnode.c,v 1.103 2018/07/16 16:44:09 helg Exp $ */
/* $NetBSD: uvm_vnode.c,v 1.36 2000/11/24 20:34:01 chs Exp $ */
/*
* then return "text busy"
* nfs_open: seems to uncache any file opened with nfs
* vn_writechk: if VTEXT vnode and can't uncache return "text busy"
+ * fusefs_open: uncaches any file that is opened
+ * fusefs_write: uncaches on every write
*/
int
* us.
*
* called from:
- * => truncate fns (ext2fs_truncate, ffs_truncate, detrunc[msdos])
- * => "write" fns (ext2fs_write, WRITE [ufs/ufs], msdosfs_write, nfs_write)
+ * => truncate fns (ext2fs_truncate, ffs_truncate, detrunc[msdos],
+ * fusefs_setattr)
+ * => "write" fns (ext2fs_write, WRITE [ufs/ufs], msdosfs_write, nfs_write
+ * fusefs_write)
* => ffs_balloc [XXX: why? doesn't WRITE handle?]
* => NFS: nfs_loadattrcache, nfs_getattrcache, nfs_setattr
* => union fs: union_newsize