summaryrefslogtreecommitdiffstats
path: root/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zap_micro.c
diff options
context:
space:
mode:
authorpjd <pjd@FreeBSD.org>2009-09-13 10:12:29 +0000
committerpjd <pjd@FreeBSD.org>2009-09-13 10:12:29 +0000
commitb9fdb7868d885d706ee9c3a5a9a647015c0bbc48 (patch)
tree85b4d92afdb97a80fc5ceddf08b86e9523aa146b /sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zap_micro.c
parentb7a222746c6fbb5db1c98e93e66ae5332a1326ef (diff)
downloadFreeBSD-src-b9fdb7868d885d706ee9c3a5a9a647015c0bbc48.zip
FreeBSD-src-b9fdb7868d885d706ee9c3a5a9a647015c0bbc48.tar.gz
There is a bug where mze_insert() can trigger an assert() of inserting
the same entry twice. This bug is not fixed yet, but leads to situation where when try to access corrupted directory the kernel will panic. Until the bug is properly fixed, try to recover from it and log that it happened. Reported by: marck OpenSolaris bug: 6709336 MFC after: 3 days
Diffstat (limited to 'sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zap_micro.c')
-rw-r--r--sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zap_micro.c21
1 files changed, 16 insertions, 5 deletions
diff --git a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zap_micro.c b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zap_micro.c
index 75b43a6..cf99222 100644
--- a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zap_micro.c
+++ b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zap_micro.c
@@ -181,10 +181,11 @@ mze_compare(const void *arg1, const void *arg2)
return (0);
}
-static void
+static int
mze_insert(zap_t *zap, int chunkid, uint64_t hash, mzap_ent_phys_t *mzep)
{
mzap_ent_t *mze;
+ avl_index_t idx;
ASSERT(zap->zap_ismicro);
ASSERT(RW_WRITE_HELD(&zap->zap_rwlock));
@@ -194,7 +195,12 @@ mze_insert(zap_t *zap, int chunkid, uint64_t hash, mzap_ent_phys_t *mzep)
mze->mze_chunkid = chunkid;
mze->mze_hash = hash;
mze->mze_phys = *mzep;
- avl_add(&zap->zap_m.zap_avl, mze);
+ if (avl_find(&zap->zap_m.zap_avl, mze, &idx) != NULL) {
+ kmem_free(mze, sizeof (mzap_ent_t));
+ return (EEXIST);
+ }
+ avl_insert(&zap->zap_m.zap_avl, mze, idx);
+ return (0);
}
static mzap_ent_t *
@@ -329,10 +335,15 @@ mzap_open(objset_t *os, uint64_t obj, dmu_buf_t *db)
if (mze->mze_name[0]) {
zap_name_t *zn;
- zap->zap_m.zap_num_entries++;
zn = zap_name_alloc(zap, mze->mze_name,
MT_EXACT);
- mze_insert(zap, i, zn->zn_hash, mze);
+ if (mze_insert(zap, i, zn->zn_hash, mze) == 0)
+ zap->zap_m.zap_num_entries++;
+ else {
+ printf("ZFS WARNING: Duplicated ZAP "
+ "entry detected (%s).",
+ mze->mze_name);
+ }
zap_name_free(zn);
}
}
@@ -771,7 +782,7 @@ again:
if (zap->zap_m.zap_alloc_next ==
zap->zap_m.zap_num_chunks)
zap->zap_m.zap_alloc_next = 0;
- mze_insert(zap, i, zn->zn_hash, mze);
+ VERIFY(0 == mze_insert(zap, i, zn->zn_hash, mze));
return;
}
}
OpenPOWER on IntegriCloud