Date: Sun, 13 Sep 2009 10:12:30 +0000 (UTC) From: Pawel Jakub Dawidek <pjd@FreeBSD.org> To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r197150 - head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs Message-ID: <200909131012.n8DACUm5013428@svn.freebsd.org>
next in thread | raw e-mail | index | archive | help
Author: pjd Date: Sun Sep 13 10:12:29 2009 New Revision: 197150 URL: http://svn.freebsd.org/changeset/base/197150 Log: 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 Modified: head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zap_micro.c Modified: head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zap_micro.c ============================================================================== --- head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zap_micro.c Sun Sep 13 10:04:08 2009 (r197149) +++ head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zap_micro.c Sun Sep 13 10:12:29 2009 (r197150) @@ -181,10 +181,11 @@ mze_compare(const void *arg1, const void 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, uint 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, dm 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; } }
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200909131012.n8DACUm5013428>