svn commit: r197479 - in stable/7/sys: . cddl/contrib/opensolaris/uts/common/fs/zfs contrib/pf

Dmitry Morozovsky marck at FreeBSD.org
Fri Sep 25 07:57:29 UTC 2009


Author: marck (doc committer)
Date: Fri Sep 25 07:57:28 2009
New Revision: 197479
URL: http://svn.freebsd.org/changeset/base/197479

Log:
  MFC r197150:
  
    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.
  
    OpenSolaris bug:	6709336
  
  Approved by:	pjd

Modified:
  stable/7/sys/   (props changed)
  stable/7/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zap_micro.c
  stable/7/sys/contrib/pf/   (props changed)

Modified: stable/7/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zap_micro.c
==============================================================================
--- stable/7/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zap_micro.c	Fri Sep 25 02:19:57 2009	(r197478)
+++ stable/7/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zap_micro.c	Fri Sep 25 07:57:28 2009	(r197479)
@@ -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;
 		}
 	}


More information about the svn-src-all mailing list