6407842 zfs panic when closing a file
6410836 zfs umount hang during ZFS stress testing.
--- a/usr/src/uts/common/fs/zfs/arc.c Mon Apr 17 10:16:06 2006 -0700
+++ b/usr/src/uts/common/fs/zfs/arc.c Mon Apr 17 11:37:08 2006 -0700
@@ -1077,8 +1077,8 @@
buf->b_hdr = NULL;
mutex_exit(&arc_eviction_mtx);
- ASSERT(buf->b_efunc != NULL);
- VERIFY(buf->b_efunc(buf) == 0);
+ if (buf->b_efunc != NULL)
+ VERIFY(buf->b_efunc(buf) == 0);
buf->b_efunc = NULL;
buf->b_private = NULL;
@@ -1943,15 +1943,16 @@
mutex_exit(&arc_eviction_mtx);
return (0);
} else if (buf->b_data == NULL) {
+ arc_buf_t copy = *buf; /* structure assignment */
/*
- * We are on the eviction list, pull us off.
+ * We are on the eviction list. Process this buffer
+ * now but let arc_do_user_evicts() do the reaping.
*/
- bufp = &arc_eviction_list;
- while (*bufp != buf)
- bufp = &(*bufp)->b_next;
- *bufp = buf->b_next;
+ buf->b_efunc = NULL;
+ buf->b_hdr = NULL;
mutex_exit(&arc_eviction_mtx);
- goto out;
+ VERIFY(copy.b_efunc(©) == 0);
+ return (1);
} else {
/*
* Prevent a race with arc_evict()
@@ -1998,7 +1999,7 @@
mutex_exit(&old_state->mtx);
}
mutex_exit(hash_lock);
-out:
+
VERIFY(buf->b_efunc(buf) == 0);
buf->b_efunc = NULL;
buf->b_private = NULL;
--- a/usr/src/uts/common/fs/zfs/dbuf.c Mon Apr 17 10:16:06 2006 -0700
+++ b/usr/src/uts/common/fs/zfs/dbuf.c Mon Apr 17 11:37:08 2006 -0700
@@ -1394,7 +1394,6 @@
if (!MUTEX_HELD(&db->db_mtx))
mutex_enter(&db->db_mtx);
- ASSERT(db->db_buf == buf);
ASSERT(refcount_is_zero(&db->db_holds));
if (db->db_state != DB_EVICTING) {
--- a/usr/src/uts/common/fs/zfs/dmu_tx.c Mon Apr 17 10:16:06 2006 -0700
+++ b/usr/src/uts/common/fs/zfs/dmu_tx.c Mon Apr 17 11:37:08 2006 -0700
@@ -318,7 +318,7 @@
{
ASSERT(tx->tx_txg == 0);
ASSERT(len < DMU_MAX_ACCESS);
- ASSERT(UINT64_MAX - off >= len - 1);
+ ASSERT(len == 0 || UINT64_MAX - off >= len - 1);
dmu_tx_hold_object_impl(tx, tx->tx_objset, object, THT_WRITE,
dmu_tx_hold_write_impl, off, len);
--- a/usr/src/uts/common/fs/zfs/zfs_vnops.c Mon Apr 17 10:16:06 2006 -0700
+++ b/usr/src/uts/common/fs/zfs/zfs_vnops.c Mon Apr 17 11:37:08 2006 -0700
@@ -2823,6 +2823,13 @@
top:
off = pp->p_offset;
rl = zfs_range_lock(zp, off, PAGESIZE, RL_WRITER);
+ /*
+ * Can't push pages past end-of-file.
+ */
+ if (off >= zp->z_phys->zp_size) {
+ zfs_range_unlock(zp, rl);
+ return (EIO);
+ }
len = MIN(PAGESIZE, zp->z_phys->zp_size - off);
tx = dmu_tx_create(zfsvfs->z_os);
@@ -3087,8 +3094,9 @@
klen = plsz;
koff = P2ALIGN(off, (u_offset_t)klen);
}
- if (klen > filesz)
- klen = P2ROUNDUP(filesz, (uint64_t)PAGESIZE);
+ ASSERT(koff <= filesz);
+ if (koff + klen > filesz)
+ klen = P2ROUNDUP(filesz, (uint64_t)PAGESIZE) - koff;
pp = pvn_read_kluster(vp, off, seg, addr, &io_off,
&io_len, koff, klen, 0);
}