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
This commit is contained in:
Pawel Jakub Dawidek 2009-09-13 10:12:29 +00:00
parent 6cbbe26f98
commit f53901193d

View File

@ -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 @@ mzap_addent(zap_name_t *zn, uint64_t value)
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;
}
}