Module Name: src
Committed By: manu
Date: Wed Apr 18 00:42:50 UTC 2012
Modified Files:
src/sys/fs/puffs: puffs_vnops.c
Log Message:
- Makesure update_va does not change vnode size when it should not. For
instance when doing a fault-issued VOP_GETPAGES within VOP_WRITE, changing
size leads to panic: genfs_getpages: past eof.
-Handle ticks wrap around for vnode name andattribute timeout
To generate a diff of this commit:
cvs rdiff -u -r1.165 -r1.166 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.165 src/sys/fs/puffs/puffs_vnops.c:1.166
--- src/sys/fs/puffs/puffs_vnops.c:1.165 Sun Apr 8 15:04:41 2012
+++ src/sys/fs/puffs/puffs_vnops.c Wed Apr 18 00:42:50 2012
@@ -1,4 +1,4 @@
-/* $NetBSD: puffs_vnops.c,v 1.165 2012/04/08 15:04:41 manu Exp $ */
+/* $NetBSD: puffs_vnops.c,v 1.166 2012/04/18 00:42:50 manu 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.165 2012/04/08 15:04:41 manu Exp $");
+__KERNEL_RCSID(0, "$NetBSD: puffs_vnops.c,v 1.166 2012/04/18 00:42:50 manu Exp $");
#include <sys/param.h>
#include <sys/buf.h>
@@ -299,6 +299,11 @@ const struct vnodeopv_entry_desc puffs_m
const struct vnodeopv_desc puffs_msgop_opv_desc =
{ &puffs_msgop_p, puffs_msgop_entries };
+/*
+ * for dosetattr / update_va
+ */
+#define SETATTR_CHSIZE 0x01
+#define SETATTR_ASYNC 0x02
#define ERROUT(err) \
do { \
@@ -412,7 +417,7 @@ static void callinactive(struct puffs_mo
static void callreclaim(struct puffs_mount *, puffs_cookie_t);
static int flushvncache(struct vnode *, off_t, off_t, bool);
static void update_va(struct vnode *, struct vattr *, struct vattr *,
- struct timespec *, struct timespec *);
+ struct timespec *, struct timespec *, int);
#define PUFFS_ABORT_LOOKUP 1
@@ -460,6 +465,10 @@ puffs_abortbutton(struct puffs_mount *pm
#define TTL_TO_TIMEOUT(ts) \
(hardclock_ticks + (ts->tv_sec * hz) + (ts->tv_nsec * hz / 1000000000))
+#define TTL_VALID(ts) \
+ ((ts != NULL) && !((ts->tv_sec == 0) && (ts->tv_nsec == 0)))
+#define TIMED_OUT(expire) \
+ ((int)((unsigned int)hardclock_ticks - (unsigned int)expire) > 0)
int
puffs_vnop_lookup(void *v)
{
@@ -505,7 +514,7 @@ puffs_vnop_lookup(void *v)
cvp = *ap->a_vpp;
cpn = VPTOPP(cvp);
- if (hardclock_ticks > cpn->pn_cn_timeout) {
+ if (TIMED_OUT(cpn->pn_cn_timeout)) {
cache_purge1(cvp, NULL, PURGE_CHILDREN);
/*
@@ -636,7 +645,8 @@ puffs_vnop_lookup(void *v)
if (PUFFS_USE_FS_TTL(pmp)) {
struct timespec *va_ttl = &lookup_msg->pvnr_va_ttl;
struct timespec *cn_ttl = &lookup_msg->pvnr_cn_ttl;
- update_va(vp, NULL, &lookup_msg->pvnr_va, va_ttl, cn_ttl);
+ update_va(vp, NULL, &lookup_msg->pvnr_va,
+ va_ttl, cn_ttl, SETATTR_CHSIZE);
}
*ap->a_vpp = vp;
@@ -737,7 +747,8 @@ puffs_vnop_create(void *v)
struct timespec *cn_ttl = &create_msg->pvnr_cn_ttl;
struct vattr *rvap = &create_msg->pvnr_va;
- update_va(*ap->a_vpp, NULL, rvap, va_ttl, cn_ttl);
+ update_va(*ap->a_vpp, NULL, rvap,
+ va_ttl, cn_ttl, SETATTR_CHSIZE);
}
out:
@@ -793,7 +804,8 @@ puffs_vnop_mknod(void *v)
struct timespec *cn_ttl = &mknod_msg->pvnr_cn_ttl;
struct vattr *rvap = &mknod_msg->pvnr_va;
- update_va(*ap->a_vpp, NULL, rvap, va_ttl, cn_ttl);
+ update_va(*ap->a_vpp, NULL, rvap,
+ va_ttl, cn_ttl, SETATTR_CHSIZE);
}
out:
@@ -912,11 +924,11 @@ puffs_vnop_access(void *v)
static void
update_va(struct vnode *vp, struct vattr *vap, struct vattr *rvap,
- struct timespec *va_ttl, struct timespec *cn_ttl)
+ struct timespec *va_ttl, struct timespec *cn_ttl, int flags)
{
struct puffs_node *pn = VPTOPP(vp);
- if (cn_ttl != NULL)
+ if (TTL_VALID(cn_ttl))
pn->pn_cn_timeout = TTL_TO_TIMEOUT(cn_ttl);
/*
@@ -946,7 +958,7 @@ update_va(struct vnode *vp, struct vattr
vap->va_size = pn->pn_mc_size;
}
- if (!(pn->pn_stat & PNODE_METACACHE_SIZE)) {
+ if (!(pn->pn_stat & PNODE_METACACHE_SIZE) && (flags & SETATTR_CHSIZE)) {
if (rvap->va_size != VNOVAL
&& vp->v_type != VBLK && vp->v_type != VCHR) {
uvm_vnp_setsize(vp, rvap->va_size);
@@ -954,7 +966,7 @@ update_va(struct vnode *vp, struct vattr
}
}
- if (va_ttl != NULL) {
+ if ((va_ttl != NULL) && TTL_VALID(va_ttl)) {
if (pn->pn_va_cache == NULL)
pn->pn_va_cache = pool_get(&puffs_vapool, PR_WAITOK);
@@ -1001,8 +1013,9 @@ puffs_vnop_getattr(void *v)
vap = ap->a_vap;
if (PUFFS_USE_FS_TTL(pmp)) {
- if (hardclock_ticks < pn->pn_va_timeout) {
- update_va(vp, vap, pn->pn_va_cache, NULL, NULL);
+ if (!TIMED_OUT(pn->pn_va_timeout)) {
+ update_va(vp, vap, pn->pn_va_cache,
+ NULL, NULL, SETATTR_CHSIZE);
goto out2;
}
}
@@ -1023,7 +1036,7 @@ puffs_vnop_getattr(void *v)
if (PUFFS_USE_FS_TTL(pmp))
va_ttl = &getattr_msg->pvnr_va_ttl;
- update_va(vp, vap, rvap, va_ttl, NULL);
+ update_va(vp, vap, rvap, va_ttl, NULL, SETATTR_CHSIZE);
out:
PUFFS_MSG_RELEASE(getattr);
@@ -1036,8 +1049,6 @@ puffs_vnop_getattr(void *v)
return error;
}
-#define SETATTR_CHSIZE 0x01
-#define SETATTR_ASYNC 0x02
static int
dosetattr(struct vnode *vp, struct vattr *vap, kauth_cred_t cred, int flags)
{
@@ -1103,7 +1114,7 @@ dosetattr(struct vnode *vp, struct vattr
struct timespec *va_ttl = &setattr_msg->pvnr_va_ttl;
struct vattr *rvap = &setattr_msg->pvnr_va;
- update_va(vp, NULL, rvap, va_ttl, NULL);
+ update_va(vp, NULL, rvap, va_ttl, NULL, flags);
}
PUFFS_MSG_RELEASE(setattr);
@@ -1703,7 +1714,8 @@ puffs_vnop_mkdir(void *v)
struct timespec *cn_ttl = &mkdir_msg->pvnr_cn_ttl;
struct vattr *rvap = &mkdir_msg->pvnr_va;
- update_va(*ap->a_vpp, NULL, rvap, va_ttl, cn_ttl);
+ update_va(*ap->a_vpp, NULL, rvap,
+ va_ttl, cn_ttl, SETATTR_CHSIZE);
}
out:
@@ -1866,7 +1878,8 @@ puffs_vnop_symlink(void *v)
struct timespec *cn_ttl = &symlink_msg->pvnr_cn_ttl;
struct vattr *rvap = &symlink_msg->pvnr_va;
- update_va(*ap->a_vpp, NULL, rvap, va_ttl, cn_ttl);
+ update_va(*ap->a_vpp, NULL, rvap,
+ va_ttl, cn_ttl, SETATTR_CHSIZE);
}
out: