From owner-svn-src-all@FreeBSD.ORG Sun Dec 18 12:27:46 2011 Return-Path: Delivered-To: svn-src-all@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 461F01065673; Sun, 18 Dec 2011 12:27:46 +0000 (UTC) (envelope-from pjd@FreeBSD.org) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:4f8:fff6::2c]) by mx1.freebsd.org (Postfix) with ESMTP id 1A5A18FC13; Sun, 18 Dec 2011 12:27:46 +0000 (UTC) Received: from svn.freebsd.org (localhost [127.0.0.1]) by svn.freebsd.org (8.14.4/8.14.4) with ESMTP id pBICRj8F009002; Sun, 18 Dec 2011 12:27:45 GMT (envelope-from pjd@svn.freebsd.org) Received: (from pjd@localhost) by svn.freebsd.org (8.14.4/8.14.4/Submit) id pBICRjQ3009000; Sun, 18 Dec 2011 12:27:45 GMT (envelope-from pjd@svn.freebsd.org) Message-Id: <201112181227.pBICRjQ3009000@svn.freebsd.org> From: Pawel Jakub Dawidek Date: Sun, 18 Dec 2011 12:27:45 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org X-SVN-Group: head MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Cc: Subject: svn commit: r228686 - head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs X-BeenThere: svn-src-all@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: "SVN commit messages for the entire src tree \(except for " user" and " projects" \)" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sun, 18 Dec 2011 12:27:46 -0000 Author: pjd Date: Sun Dec 18 12:27:45 2011 New Revision: 228686 URL: http://svn.freebsd.org/changeset/base/228686 Log: From time to time people report space map corruption resulting in panic (ss == NULL) on pool import. I had such a panic recently. With current version of ZFS it is still possible to import the pool in readonly mode and backup all the data, but in case it is impossible for some reason add tunable vfs.zfs.space_map_last_hope, which when set to '1' will tell ZFS to remove colliding range and retry. This seems to have worked for me, but I consider it highly risky to use. MFC after: 1 week Modified: head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/space_map.c Modified: head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/space_map.c ============================================================================== --- head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/space_map.c Sun Dec 18 12:19:03 2011 (r228685) +++ head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/space_map.c Sun Dec 18 12:27:45 2011 (r228686) @@ -29,6 +29,13 @@ #include #include +SYSCTL_DECL(_vfs_zfs); +static int space_map_last_hope; +TUNABLE_INT("vfs.zfs.space_map_last_hope", &space_map_last_hope); +SYSCTL_INT(_vfs_zfs, OID_AUTO, space_map_last_hope, CTLFLAG_RDTUN, + &space_map_last_hope, 0, + "If kernel panic in space_map code on pool import, import the pool in readonly mode and backup all your data before trying this option."); + /* * Space map routines. * NOTE: caller is responsible for all locking. @@ -93,7 +100,7 @@ space_map_add(space_map_t *sm, uint64_t VERIFY(sm->sm_space + size <= sm->sm_size); VERIFY(P2PHASE(start, 1ULL << sm->sm_shift) == 0); VERIFY(P2PHASE(size, 1ULL << sm->sm_shift) == 0); - +again: ssearch.ss_start = start; ssearch.ss_end = end; ss = avl_find(&sm->sm_root, &ssearch, &where); @@ -104,6 +111,23 @@ space_map_add(space_map_t *sm, uint64_t (longlong_t)start, (longlong_t)size); return; } + if (ss != NULL && space_map_last_hope) { + uint64_t sstart, ssize; + + if (ss->ss_start > start) + sstart = ss->ss_start; + else + sstart = start; + if (ss->ss_end > end) + ssize = end - sstart; + else + ssize = ss->ss_end - sstart; + ZFS_LOG(0, + "Removing colliding space_map range (start=%ju end=%ju). Good luck!", + (uintmax_t)sstart, (uintmax_t)(sstart + ssize)); + space_map_remove(sm, sstart, ssize); + goto again; + } /* Make sure we don't overlap with either of our neighbors */ VERIFY(ss == NULL);