diff options
author | maybee <none@none> | 2006-03-10 12:34:02 -0800 |
---|---|---|
committer | maybee <none@none> | 2006-03-10 12:34:02 -0800 |
commit | bbf4a8df08a5ccce4c75fe2b82fafa4bb55b77db (patch) | |
tree | 188282fb3dbeeca47b2804eb41227ad6c8e9412d /usr/src | |
parent | e3c625046462319a7c7ce069b2d83c1923ffc094 (diff) | |
download | illumos-gate-bbf4a8df08a5ccce4c75fe2b82fafa4bb55b77db.tar.gz |
6395526 assertion failed: refcount_count(&ab->b_refcnt) == 1 (0x2 == 0x1)
6395628 panic:assertion failed: svp->v_count == 1 (0x2 == 0x1), file: ./common/fs/zfs/zfs_ctldir.c line: 939
Diffstat (limited to 'usr/src')
-rw-r--r-- | usr/src/uts/common/fs/zfs/arc.c | 36 | ||||
-rw-r--r-- | usr/src/uts/common/fs/zfs/zfs_ctldir.c | 30 |
2 files changed, 39 insertions, 27 deletions
diff --git a/usr/src/uts/common/fs/zfs/arc.c b/usr/src/uts/common/fs/zfs/arc.c index 904e746721..9b5e279e7b 100644 --- a/usr/src/uts/common/fs/zfs/arc.c +++ b/usr/src/uts/common/fs/zfs/arc.c @@ -1565,7 +1565,7 @@ arc_getbuf_func(zio_t *zio, arc_buf_t *buf, void *arg) static void arc_read_done(zio_t *zio) { - arc_buf_hdr_t *hdr; + arc_buf_hdr_t *hdr, *found; arc_buf_t *buf; arc_buf_t *abuf; /* buffer we're assigning to callback */ kmutex_t *hash_lock; @@ -1575,22 +1575,19 @@ arc_read_done(zio_t *zio) buf = zio->io_private; hdr = buf->b_hdr; - if (!HDR_FREED_IN_READ(hdr)) { - arc_buf_hdr_t *found; - - found = buf_hash_find(zio->io_spa, &hdr->b_dva, hdr->b_birth, + /* + * The hdr was inserted into hash-table and removed from lists + * prior to starting I/O. We should find this header, since + * it's in the hash table, and it should be legit since it's + * not possible to evict it during the I/O. The only possible + * reason for it not to be found is if we were freed during the + * read. + */ + found = buf_hash_find(zio->io_spa, &hdr->b_dva, hdr->b_birth, &hash_lock); - /* - * Buffer was inserted into hash-table and removed from lists - * prior to starting I/O. We should find this header, since - * it's in the hash table, and it should be legit since it's - * not possible to evict it during the I/O. - */ - - ASSERT(found); - ASSERT(DVA_EQUAL(&hdr->b_dva, BP_IDENTITY(zio->io_bp))); - } + ASSERT((found == NULL && HDR_FREED_IN_READ(hdr) && hash_lock == NULL) || + (found == hdr && DVA_EQUAL(&hdr->b_dva, BP_IDENTITY(zio->io_bp)))); /* byteswap if necessary */ callback_list = hdr->b_acb; @@ -1656,7 +1653,7 @@ arc_read_done(zio_t *zio) */ cv_broadcast(&hdr->b_cv); - if (!HDR_FREED_IN_READ(hdr)) { + if (hash_lock) { /* * Only call arc_access on anonymous buffers. This is because * if we've issued an I/O for an evicted buffer, we've already @@ -2246,7 +2243,12 @@ arc_free(zio_t *pio, spa_t *spa, uint64_t txg, blkptr_t *bp, arc_hdr_destroy(ab); atomic_add_64(&arc.deleted, 1); } else { - ASSERT3U(refcount_count(&ab->b_refcnt), ==, 1); + /* + * We could have an outstanding read on this + * block, so multiple active references are + * possible. But we should only have a single + * data buffer associated at this point. + */ ASSERT3U(ab->b_datacnt, ==, 1); if (HDR_IO_IN_PROGRESS(ab)) ab->b_flags |= ARC_FREED_IN_READ; diff --git a/usr/src/uts/common/fs/zfs/zfs_ctldir.c b/usr/src/uts/common/fs/zfs/zfs_ctldir.c index 7b267b5a38..c4751b879c 100644 --- a/usr/src/uts/common/fs/zfs/zfs_ctldir.c +++ b/usr/src/uts/common/fs/zfs/zfs_ctldir.c @@ -431,8 +431,11 @@ zfsctl_unmount_snap(vnode_t *dvp, const char *name, int force, cred_t *cr) return (err); VN_HOLD(sep->se_root); - if ((err = dounmount(vn_mountedvfs(sep->se_root), force, kcred)) != 0) + err = dounmount(vn_mountedvfs(sep->se_root), force, kcred); + if (err) { + VN_RELE(sep->se_root); return (err); + } ASSERT(sep->se_root->v_count == 1); gfs_vop_inactive(sep->se_root, cr); @@ -618,17 +621,20 @@ zfsctl_snapdir_lookup(vnode_t *dvp, char *nm, vnode_t **vpp, pathname_t *pnp, if ((sep = avl_find(&sdp->sd_snaps, &search, &where)) != NULL) { *vpp = sep->se_root; VN_HOLD(*vpp); - /* - * If the snapshot was unmounted behind our backs, - * try to remount it. - */ - if (traverse(vpp) != 0) { - ASSERT(!vn_ismntpt(*vpp)); + err = traverse(vpp); + if (err) { + VN_RELE(*vpp); + *vpp = NULL; + } else if (*vpp == sep->se_root) { + /* + * The snapshot was unmounted behind our backs, + * try to remount it. + */ goto domount; } mutex_exit(&sdp->sd_lock); ZFS_EXIT(zfsvfs); - return (0); + return (err); } /* @@ -898,8 +904,12 @@ zfsctl_lookup_objset(vfs_t *vfsp, uint64_t objsetid, zfsvfs_t **zfsvfsp) if (sep != NULL) { VN_HOLD(vp); error = traverse(&vp); - if (error == 0) - *zfsvfsp = VTOZ(vp)->z_zfsvfs; + if (error == 0) { + if (vp == sep->se_root) + error = EINVAL; + else + *zfsvfsp = VTOZ(vp)->z_zfsvfs; + } mutex_exit(&sdp->sd_lock); VN_RELE(vp); } else { |