Module Name: src Committed By: msaitoh Date: Sun Nov 9 06:28:03 UTC 2014
Modified Files: src/sys/fs/puffs [netbsd-6]: puffs_vnops.c Log Message: Pull up following revision(s) (requested by manu in ticket #1166): sys/fs/puffs/puffs_vnops.c: revision 1.188-1.194 - If we truncate the file, make sure we zero-fill the end of the last page, otherwise if the file is later truncated to a larger size (creating a hole), that area will not return zeroes as it should. - Use PRIx64 for printing offsets - Improve zero-fill of last page after shrink fix: 1) do it only if the file is open for writing, otherwise we send write requests to the FS on a file that has never been open. 2) do it inside existing if (vap->va_size != VNOVAL) block - Retore LP64 fix that was removed by mistake - Make this build again without debugging enabled; DPRINTF() can end up as empty, and in an if conditional, you then need braces if that's the only potential body. - As is evidenced by several of our 32-bit MIPS ports, it's wrong to print vsize_t with PRIx64 -- instead use our own PRIxVSIZE macro. - Do the previous correctly... To generate a diff of this commit: cvs rdiff -u -r1.163.2.7 -r1.163.2.8 src/sys/fs/puffs/puffs_vnops.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
Modified files: Index: src/sys/fs/puffs/puffs_vnops.c diff -u src/sys/fs/puffs/puffs_vnops.c:1.163.2.7 src/sys/fs/puffs/puffs_vnops.c:1.163.2.8 --- src/sys/fs/puffs/puffs_vnops.c:1.163.2.7 Mon Nov 3 19:51:36 2014 +++ src/sys/fs/puffs/puffs_vnops.c Sun Nov 9 06:28:03 2014 @@ -1,4 +1,4 @@ -/* $NetBSD: puffs_vnops.c,v 1.163.2.7 2014/11/03 19:51:36 msaitoh Exp $ */ +/* $NetBSD: puffs_vnops.c,v 1.163.2.8 2014/11/09 06:28:03 msaitoh Exp $ */ /* * Copyright (c) 2005, 2006, 2007 Antti Kantee. All Rights Reserved. @@ -30,7 +30,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: puffs_vnops.c,v 1.163.2.7 2014/11/03 19:51:36 msaitoh Exp $"); +__KERNEL_RCSID(0, "$NetBSD: puffs_vnops.c,v 1.163.2.8 2014/11/09 06:28:03 msaitoh Exp $"); #include <sys/param.h> #include <sys/buf.h> @@ -1117,12 +1117,50 @@ puffs_vnop_getattr(void *v) return error; } +static void +zerofill_lastpage(struct vnode *vp, voff_t off) +{ + char zbuf[PAGE_SIZE]; + struct iovec iov; + struct uio uio; + vsize_t len; + int error; + + if (trunc_page(off) == off) + return; + + if (vp->v_writecount == 0) + return; + + len = round_page(off) - off; + memset(zbuf, 0, len); + + iov.iov_base = zbuf; + iov.iov_len = len; + UIO_SETUP_SYSSPACE(&uio); + uio.uio_iov = &iov; + uio.uio_iovcnt = 1; + uio.uio_offset = off; + uio.uio_resid = len; + uio.uio_rw = UIO_WRITE; + + error = ubc_uiomove(&vp->v_uobj, &uio, len, + UVM_ADV_SEQUENTIAL, UBC_WRITE|UBC_UNMAP_FLAG(vp)); + if (error) { + DPRINTF(("zero-fill 0x%" PRIxVSIZE "@0x%" PRIx64 + " failed: error = %d\n", len, off, error)); + } + + return; +} + static int dosetattr(struct vnode *vp, struct vattr *vap, kauth_cred_t cred, int flags) { PUFFS_MSG_VARS(vn, setattr); struct puffs_mount *pmp = MPTOPUFFSMP(vp->v_mount); struct puffs_node *pn = vp->v_data; + vsize_t oldsize = vp->v_size; int error = 0; KASSERT(!(flags & SETATTR_CHSIZE) || mutex_owned(&pn->pn_sizemtx)); @@ -1195,6 +1233,17 @@ dosetattr(struct vnode *vp, struct vattr } if (vap->va_size != VNOVAL) { + /* + * If we truncated the file, make sure the data beyond + * EOF in last page does not remain in cache, otherwise + * if the file is later truncated to a larger size (creating + * a hole), that area will not return zeroes as it + * should. + */ + if ((flags & SETATTR_CHSIZE) && PUFFS_USE_PAGECACHE(pmp) && + (vap->va_size < oldsize)) + zerofill_lastpage(vp, vap->va_size); + pn->pn_serversize = vap->va_size; if (flags & SETATTR_CHSIZE) uvm_vnp_setsize(vp, vap->va_size);