Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/sys/fs/puffs - Makesure update_va does not change vnode size...



details:   https://anonhg.NetBSD.org/src/rev/3a084e7c378a
branches:  trunk
changeset: 778871:3a084e7c378a
user:      manu <manu%NetBSD.org@localhost>
date:      Wed Apr 18 00:42:50 2012 +0000

description:
- 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

diffstat:

 sys/fs/puffs/puffs_vnops.c |  51 ++++++++++++++++++++++++++++-----------------
 1 files changed, 32 insertions(+), 19 deletions(-)

diffs (180 lines):

diff -r b853a30ca297 -r 3a084e7c378a sys/fs/puffs/puffs_vnops.c
--- a/sys/fs/puffs/puffs_vnops.c        Tue Apr 17 21:39:19 2012 +0000
+++ b/sys/fs/puffs/puffs_vnops.c        Wed Apr 18 00:42:50 2012 +0000
@@ -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_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 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 @@
 
 #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 @@
 
                        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 @@
        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 @@
                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 @@
                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 @@
 
 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 @@
                        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 @@
                }
        }
 
-       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 @@
        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 @@
        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 @@
        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 @@
                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 @@
                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 @@
                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:



Home | Main Index | Thread Index | Old Index