hammer - Attempt to fix improper call to vsetisdirty() in hammer flush
authorMatthew Dillon <dillon@apollo.backplane.com>
Mon, 19 Jan 2015 04:17:42 +0000 (20:17 -0800)
committerMatthew Dillon <dillon@apollo.backplane.com>
Mon, 19 Jan 2015 04:17:42 +0000 (20:17 -0800)
* The hammer flush occurs in the background.  Because of this it is possible
  for a vnode to be reclaimed just prior to the flush code getting to it.

* Attempt to fix an improper call to vsetisdirty() which can panic the machine
  on vp->v_mount becoming NULL.  The vnode reclamation should theoretically be
  interlocked against the inode lock so it should suffice to simply check
  to see if it has been reclaimed yet or not.

* Also don't bother marking the vnode dirty if it is already marked dirty.

sys/vfs/hammer/hammer_inode.c

index 608d49b..33a6a88 100644 (file)
@@ -252,6 +252,11 @@ hammer_vop_reclaim(struct vop_reclaim_args *ap)
 /*
  * Inform the kernel that the inode is dirty.  This will be checked
  * by vn_unlock().
+ *
+ * Theoretically in order to reclaim a vnode the hammer_vop_reclaim()
+ * must be called which will interlock against our inode lock, so
+ * if VRECLAIMED is not set vp->v_mount (as used by vsetisdirty())
+ * should be stable without having to acquire any new locks.
  */
 void
 hammer_inode_dirty(struct hammer_inode *ip)
@@ -259,7 +264,8 @@ hammer_inode_dirty(struct hammer_inode *ip)
        struct vnode *vp;
 
        if ((ip->flags & HAMMER_INODE_MODMASK) &&
-           (vp = ip->vp) != NULL) {
+           (vp = ip->vp) != NULL &&
+           (vp->v_flag & (VRECLAIMED | VISDIRTY)) == 0) {
                vsetisdirty(vp);
        }
 }