usr/src/uts/common/fs/zfs/space_map.c
author Joshua M. Clulow <jmc@joyent.com>
Mon, 04 Mar 2013 23:52:56 +0000
changeset 14188 afe390b9f1e0
parent 13973 4972ab336f54
permissions -rw-r--r--
4020 Make ldi_ev_remove_callbacks safe to use in LDI callbacks Reviewed by: Robert Mustacchi <[email protected]> Approved by: Dan McDonald <[email protected]>
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
     1
/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
     2
 * CDDL HEADER START
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
     3
 *
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
     4
 * The contents of this file are subject to the terms of the
1544
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 789
diff changeset
     5
 * Common Development and Distribution License (the "License").
938876158511 PSARC 2006/077 zpool clear
eschrock
parents: 789
diff changeset
     6
 * You may not use this file except in compliance with the License.
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
     7
 *
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
     8
 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
     9
 * or http://www.opensolaris.org/os/licensing.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    10
 * See the License for the specific language governing permissions
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    11
 * and limitations under the License.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    12
 *
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    13
 * When distributing Covered Code, include this CDDL HEADER in each
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    14
 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    15
 * If applicable, add the following below this CDDL HEADER, with the
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    16
 * fields enclosed by brackets "[]" replaced with your own identifying
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    17
 * information: Portions Copyright [yyyy] [name of copyright owner]
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    18
 *
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    19
 * CDDL HEADER END
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    20
 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    21
/*
9480
fcff33da767f 6596237 Stop looking and start ganging
George Wilson <George.Wilson@Sun.COM>
parents: 8241
diff changeset
    22
 * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    23
 * Use is subject to license terms.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    24
 */
13805
e3a9ae14a119 3006 VERIFY[S,U,P] and ASSERT[S,U,P] frequently check if first argument is zero
Madhav Suresh <madhav.suresh@delphix.com>
parents: 13765
diff changeset
    25
/*
e3a9ae14a119 3006 VERIFY[S,U,P] and ASSERT[S,U,P] frequently check if first argument is zero
Madhav Suresh <madhav.suresh@delphix.com>
parents: 13765
diff changeset
    26
 * Copyright (c) 2012 by Delphix. All rights reserved.
e3a9ae14a119 3006 VERIFY[S,U,P] and ASSERT[S,U,P] frequently check if first argument is zero
Madhav Suresh <madhav.suresh@delphix.com>
parents: 13765
diff changeset
    27
 */
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    28
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    29
#include <sys/zfs_context.h>
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    30
#include <sys/spa.h>
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    31
#include <sys/dmu.h>
1732
9e3ae798af31 6280668 pluggable block allocation policy
bonwick
parents: 1544
diff changeset
    32
#include <sys/zio.h>
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    33
#include <sys/space_map.h>
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    34
13879
4eac7a87eff2 3329 spa_sync() spends 10-20% of its time in spa_free_sync_cb()
George Wilson <george.wilson@delphix.com>
parents: 13805
diff changeset
    35
static kmem_cache_t *space_seg_cache;
4eac7a87eff2 3329 spa_sync() spends 10-20% of its time in spa_free_sync_cb()
George Wilson <george.wilson@delphix.com>
parents: 13805
diff changeset
    36
4eac7a87eff2 3329 spa_sync() spends 10-20% of its time in spa_free_sync_cb()
George Wilson <george.wilson@delphix.com>
parents: 13805
diff changeset
    37
void
4eac7a87eff2 3329 spa_sync() spends 10-20% of its time in spa_free_sync_cb()
George Wilson <george.wilson@delphix.com>
parents: 13805
diff changeset
    38
space_map_init(void)
4eac7a87eff2 3329 spa_sync() spends 10-20% of its time in spa_free_sync_cb()
George Wilson <george.wilson@delphix.com>
parents: 13805
diff changeset
    39
{
4eac7a87eff2 3329 spa_sync() spends 10-20% of its time in spa_free_sync_cb()
George Wilson <george.wilson@delphix.com>
parents: 13805
diff changeset
    40
	ASSERT(space_seg_cache == NULL);
4eac7a87eff2 3329 spa_sync() spends 10-20% of its time in spa_free_sync_cb()
George Wilson <george.wilson@delphix.com>
parents: 13805
diff changeset
    41
	space_seg_cache = kmem_cache_create("space_seg_cache",
4eac7a87eff2 3329 spa_sync() spends 10-20% of its time in spa_free_sync_cb()
George Wilson <george.wilson@delphix.com>
parents: 13805
diff changeset
    42
	    sizeof (space_seg_t), 0, NULL, NULL, NULL, NULL, NULL, 0);
4eac7a87eff2 3329 spa_sync() spends 10-20% of its time in spa_free_sync_cb()
George Wilson <george.wilson@delphix.com>
parents: 13805
diff changeset
    43
}
4eac7a87eff2 3329 spa_sync() spends 10-20% of its time in spa_free_sync_cb()
George Wilson <george.wilson@delphix.com>
parents: 13805
diff changeset
    44
4eac7a87eff2 3329 spa_sync() spends 10-20% of its time in spa_free_sync_cb()
George Wilson <george.wilson@delphix.com>
parents: 13805
diff changeset
    45
void
4eac7a87eff2 3329 spa_sync() spends 10-20% of its time in spa_free_sync_cb()
George Wilson <george.wilson@delphix.com>
parents: 13805
diff changeset
    46
space_map_fini(void)
4eac7a87eff2 3329 spa_sync() spends 10-20% of its time in spa_free_sync_cb()
George Wilson <george.wilson@delphix.com>
parents: 13805
diff changeset
    47
{
4eac7a87eff2 3329 spa_sync() spends 10-20% of its time in spa_free_sync_cb()
George Wilson <george.wilson@delphix.com>
parents: 13805
diff changeset
    48
	kmem_cache_destroy(space_seg_cache);
4eac7a87eff2 3329 spa_sync() spends 10-20% of its time in spa_free_sync_cb()
George Wilson <george.wilson@delphix.com>
parents: 13805
diff changeset
    49
	space_seg_cache = NULL;
4eac7a87eff2 3329 spa_sync() spends 10-20% of its time in spa_free_sync_cb()
George Wilson <george.wilson@delphix.com>
parents: 13805
diff changeset
    50
}
4eac7a87eff2 3329 spa_sync() spends 10-20% of its time in spa_free_sync_cb()
George Wilson <george.wilson@delphix.com>
parents: 13805
diff changeset
    51
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    52
/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    53
 * Space map routines.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    54
 * NOTE: caller is responsible for all locking.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    55
 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    56
static int
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    57
space_map_seg_compare(const void *x1, const void *x2)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    58
{
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    59
	const space_seg_t *s1 = x1;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    60
	const space_seg_t *s2 = x2;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    61
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    62
	if (s1->ss_start < s2->ss_start) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    63
		if (s1->ss_end > s2->ss_start)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    64
			return (0);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    65
		return (-1);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    66
	}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    67
	if (s1->ss_start > s2->ss_start) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    68
		if (s1->ss_start < s2->ss_end)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    69
			return (0);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    70
		return (1);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    71
	}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    72
	return (0);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    73
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    74
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    75
void
1732
9e3ae798af31 6280668 pluggable block allocation policy
bonwick
parents: 1544
diff changeset
    76
space_map_create(space_map_t *sm, uint64_t start, uint64_t size, uint8_t shift,
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    77
	kmutex_t *lp)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    78
{
1732
9e3ae798af31 6280668 pluggable block allocation policy
bonwick
parents: 1544
diff changeset
    79
	bzero(sm, sizeof (*sm));
9e3ae798af31 6280668 pluggable block allocation policy
bonwick
parents: 1544
diff changeset
    80
8214
d7abf7c1f1c1 6747934 Some locking variables are not properly initialized or destroyed
Ricardo M. Correia <Ricardo.M.Correia@Sun.COM>
parents: 6227
diff changeset
    81
	cv_init(&sm->sm_load_cv, NULL, CV_DEFAULT, NULL);
d7abf7c1f1c1 6747934 Some locking variables are not properly initialized or destroyed
Ricardo M. Correia <Ricardo.M.Correia@Sun.COM>
parents: 6227
diff changeset
    82
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    83
	avl_create(&sm->sm_root, space_map_seg_compare,
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    84
	    sizeof (space_seg_t), offsetof(struct space_seg, ss_node));
1732
9e3ae798af31 6280668 pluggable block allocation policy
bonwick
parents: 1544
diff changeset
    85
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    86
	sm->sm_start = start;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    87
	sm->sm_size = size;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    88
	sm->sm_shift = shift;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    89
	sm->sm_lock = lp;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    90
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    91
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    92
void
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    93
space_map_destroy(space_map_t *sm)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    94
{
1732
9e3ae798af31 6280668 pluggable block allocation policy
bonwick
parents: 1544
diff changeset
    95
	ASSERT(!sm->sm_loaded && !sm->sm_loading);
13805
e3a9ae14a119 3006 VERIFY[S,U,P] and ASSERT[S,U,P] frequently check if first argument is zero
Madhav Suresh <madhav.suresh@delphix.com>
parents: 13765
diff changeset
    96
	VERIFY0(sm->sm_space);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    97
	avl_destroy(&sm->sm_root);
8214
d7abf7c1f1c1 6747934 Some locking variables are not properly initialized or destroyed
Ricardo M. Correia <Ricardo.M.Correia@Sun.COM>
parents: 6227
diff changeset
    98
	cv_destroy(&sm->sm_load_cv);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    99
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   100
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   101
void
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   102
space_map_add(space_map_t *sm, uint64_t start, uint64_t size)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   103
{
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   104
	avl_index_t where;
13973
4972ab336f54 3464 zfs synctask code needs restructuring
Matthew Ahrens <mahrens@delphix.com>
parents: 13959
diff changeset
   105
	space_seg_t *ss_before, *ss_after, *ss;
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   106
	uint64_t end = start + size;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   107
	int merge_before, merge_after;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   108
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   109
	ASSERT(MUTEX_HELD(sm->sm_lock));
13959
e03e14ddfb4c 3552 condensing one space map burns 3 seconds of CPU in spa_sync() thread
George Wilson <george.wilson@delphix.com>
parents: 13879
diff changeset
   110
	VERIFY(!sm->sm_condensing);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   111
	VERIFY(size != 0);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   112
	VERIFY3U(start, >=, sm->sm_start);
1732
9e3ae798af31 6280668 pluggable block allocation policy
bonwick
parents: 1544
diff changeset
   113
	VERIFY3U(end, <=, sm->sm_start + sm->sm_size);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   114
	VERIFY(sm->sm_space + size <= sm->sm_size);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   115
	VERIFY(P2PHASE(start, 1ULL << sm->sm_shift) == 0);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   116
	VERIFY(P2PHASE(size, 1ULL << sm->sm_shift) == 0);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   117
13973
4972ab336f54 3464 zfs synctask code needs restructuring
Matthew Ahrens <mahrens@delphix.com>
parents: 13959
diff changeset
   118
	ss = space_map_find(sm, start, size, &where);
4972ab336f54 3464 zfs synctask code needs restructuring
Matthew Ahrens <mahrens@delphix.com>
parents: 13959
diff changeset
   119
	if (ss != NULL) {
3713
00e75dc8b749 6527325 want more assertions in space map code
ahrens
parents: 1732
diff changeset
   120
		zfs_panic_recover("zfs: allocating allocated segment"
00e75dc8b749 6527325 want more assertions in space map code
ahrens
parents: 1732
diff changeset
   121
		    "(offset=%llu size=%llu)\n",
00e75dc8b749 6527325 want more assertions in space map code
ahrens
parents: 1732
diff changeset
   122
		    (longlong_t)start, (longlong_t)size);
00e75dc8b749 6527325 want more assertions in space map code
ahrens
parents: 1732
diff changeset
   123
		return;
00e75dc8b749 6527325 want more assertions in space map code
ahrens
parents: 1732
diff changeset
   124
	}
00e75dc8b749 6527325 want more assertions in space map code
ahrens
parents: 1732
diff changeset
   125
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   126
	/* Make sure we don't overlap with either of our neighbors */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   127
	VERIFY(ss == NULL);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   128
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   129
	ss_before = avl_nearest(&sm->sm_root, where, AVL_BEFORE);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   130
	ss_after = avl_nearest(&sm->sm_root, where, AVL_AFTER);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   131
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   132
	merge_before = (ss_before != NULL && ss_before->ss_end == start);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   133
	merge_after = (ss_after != NULL && ss_after->ss_start == end);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   134
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   135
	if (merge_before && merge_after) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   136
		avl_remove(&sm->sm_root, ss_before);
9480
fcff33da767f 6596237 Stop looking and start ganging
George Wilson <George.Wilson@Sun.COM>
parents: 8241
diff changeset
   137
		if (sm->sm_pp_root) {
fcff33da767f 6596237 Stop looking and start ganging
George Wilson <George.Wilson@Sun.COM>
parents: 8241
diff changeset
   138
			avl_remove(sm->sm_pp_root, ss_before);
fcff33da767f 6596237 Stop looking and start ganging
George Wilson <George.Wilson@Sun.COM>
parents: 8241
diff changeset
   139
			avl_remove(sm->sm_pp_root, ss_after);
fcff33da767f 6596237 Stop looking and start ganging
George Wilson <George.Wilson@Sun.COM>
parents: 8241
diff changeset
   140
		}
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   141
		ss_after->ss_start = ss_before->ss_start;
13879
4eac7a87eff2 3329 spa_sync() spends 10-20% of its time in spa_free_sync_cb()
George Wilson <george.wilson@delphix.com>
parents: 13805
diff changeset
   142
		kmem_cache_free(space_seg_cache, ss_before);
9480
fcff33da767f 6596237 Stop looking and start ganging
George Wilson <George.Wilson@Sun.COM>
parents: 8241
diff changeset
   143
		ss = ss_after;
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   144
	} else if (merge_before) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   145
		ss_before->ss_end = end;
9480
fcff33da767f 6596237 Stop looking and start ganging
George Wilson <George.Wilson@Sun.COM>
parents: 8241
diff changeset
   146
		if (sm->sm_pp_root)
fcff33da767f 6596237 Stop looking and start ganging
George Wilson <George.Wilson@Sun.COM>
parents: 8241
diff changeset
   147
			avl_remove(sm->sm_pp_root, ss_before);
fcff33da767f 6596237 Stop looking and start ganging
George Wilson <George.Wilson@Sun.COM>
parents: 8241
diff changeset
   148
		ss = ss_before;
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   149
	} else if (merge_after) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   150
		ss_after->ss_start = start;
9480
fcff33da767f 6596237 Stop looking and start ganging
George Wilson <George.Wilson@Sun.COM>
parents: 8241
diff changeset
   151
		if (sm->sm_pp_root)
fcff33da767f 6596237 Stop looking and start ganging
George Wilson <George.Wilson@Sun.COM>
parents: 8241
diff changeset
   152
			avl_remove(sm->sm_pp_root, ss_after);
fcff33da767f 6596237 Stop looking and start ganging
George Wilson <George.Wilson@Sun.COM>
parents: 8241
diff changeset
   153
		ss = ss_after;
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   154
	} else {
13879
4eac7a87eff2 3329 spa_sync() spends 10-20% of its time in spa_free_sync_cb()
George Wilson <george.wilson@delphix.com>
parents: 13805
diff changeset
   155
		ss = kmem_cache_alloc(space_seg_cache, KM_SLEEP);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   156
		ss->ss_start = start;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   157
		ss->ss_end = end;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   158
		avl_insert(&sm->sm_root, ss, where);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   159
	}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   160
9480
fcff33da767f 6596237 Stop looking and start ganging
George Wilson <George.Wilson@Sun.COM>
parents: 8241
diff changeset
   161
	if (sm->sm_pp_root)
fcff33da767f 6596237 Stop looking and start ganging
George Wilson <George.Wilson@Sun.COM>
parents: 8241
diff changeset
   162
		avl_add(sm->sm_pp_root, ss);
fcff33da767f 6596237 Stop looking and start ganging
George Wilson <George.Wilson@Sun.COM>
parents: 8241
diff changeset
   163
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   164
	sm->sm_space += size;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   165
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   166
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   167
void
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   168
space_map_remove(space_map_t *sm, uint64_t start, uint64_t size)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   169
{
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   170
	avl_index_t where;
13973
4972ab336f54 3464 zfs synctask code needs restructuring
Matthew Ahrens <mahrens@delphix.com>
parents: 13959
diff changeset
   171
	space_seg_t *ss, *newseg;
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   172
	uint64_t end = start + size;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   173
	int left_over, right_over;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   174
13959
e03e14ddfb4c 3552 condensing one space map burns 3 seconds of CPU in spa_sync() thread
George Wilson <george.wilson@delphix.com>
parents: 13879
diff changeset
   175
	VERIFY(!sm->sm_condensing);
13973
4972ab336f54 3464 zfs synctask code needs restructuring
Matthew Ahrens <mahrens@delphix.com>
parents: 13959
diff changeset
   176
	ss = space_map_find(sm, start, size, &where);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   177
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   178
	/* Make sure we completely overlap with someone */
3713
00e75dc8b749 6527325 want more assertions in space map code
ahrens
parents: 1732
diff changeset
   179
	if (ss == NULL) {
00e75dc8b749 6527325 want more assertions in space map code
ahrens
parents: 1732
diff changeset
   180
		zfs_panic_recover("zfs: freeing free segment "
00e75dc8b749 6527325 want more assertions in space map code
ahrens
parents: 1732
diff changeset
   181
		    "(offset=%llu size=%llu)",
00e75dc8b749 6527325 want more assertions in space map code
ahrens
parents: 1732
diff changeset
   182
		    (longlong_t)start, (longlong_t)size);
00e75dc8b749 6527325 want more assertions in space map code
ahrens
parents: 1732
diff changeset
   183
		return;
00e75dc8b749 6527325 want more assertions in space map code
ahrens
parents: 1732
diff changeset
   184
	}
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   185
	VERIFY3U(ss->ss_start, <=, start);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   186
	VERIFY3U(ss->ss_end, >=, end);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   187
	VERIFY(sm->sm_space - size <= sm->sm_size);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   188
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   189
	left_over = (ss->ss_start != start);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   190
	right_over = (ss->ss_end != end);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   191
9480
fcff33da767f 6596237 Stop looking and start ganging
George Wilson <George.Wilson@Sun.COM>
parents: 8241
diff changeset
   192
	if (sm->sm_pp_root)
fcff33da767f 6596237 Stop looking and start ganging
George Wilson <George.Wilson@Sun.COM>
parents: 8241
diff changeset
   193
		avl_remove(sm->sm_pp_root, ss);
fcff33da767f 6596237 Stop looking and start ganging
George Wilson <George.Wilson@Sun.COM>
parents: 8241
diff changeset
   194
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   195
	if (left_over && right_over) {
13879
4eac7a87eff2 3329 spa_sync() spends 10-20% of its time in spa_free_sync_cb()
George Wilson <george.wilson@delphix.com>
parents: 13805
diff changeset
   196
		newseg = kmem_cache_alloc(space_seg_cache, KM_SLEEP);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   197
		newseg->ss_start = end;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   198
		newseg->ss_end = ss->ss_end;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   199
		ss->ss_end = start;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   200
		avl_insert_here(&sm->sm_root, newseg, ss, AVL_AFTER);
9480
fcff33da767f 6596237 Stop looking and start ganging
George Wilson <George.Wilson@Sun.COM>
parents: 8241
diff changeset
   201
		if (sm->sm_pp_root)
fcff33da767f 6596237 Stop looking and start ganging
George Wilson <George.Wilson@Sun.COM>
parents: 8241
diff changeset
   202
			avl_add(sm->sm_pp_root, newseg);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   203
	} else if (left_over) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   204
		ss->ss_end = start;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   205
	} else if (right_over) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   206
		ss->ss_start = end;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   207
	} else {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   208
		avl_remove(&sm->sm_root, ss);
13879
4eac7a87eff2 3329 spa_sync() spends 10-20% of its time in spa_free_sync_cb()
George Wilson <george.wilson@delphix.com>
parents: 13805
diff changeset
   209
		kmem_cache_free(space_seg_cache, ss);
9480
fcff33da767f 6596237 Stop looking and start ganging
George Wilson <George.Wilson@Sun.COM>
parents: 8241
diff changeset
   210
		ss = NULL;
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   211
	}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   212
9480
fcff33da767f 6596237 Stop looking and start ganging
George Wilson <George.Wilson@Sun.COM>
parents: 8241
diff changeset
   213
	if (sm->sm_pp_root && ss != NULL)
fcff33da767f 6596237 Stop looking and start ganging
George Wilson <George.Wilson@Sun.COM>
parents: 8241
diff changeset
   214
		avl_add(sm->sm_pp_root, ss);
fcff33da767f 6596237 Stop looking and start ganging
George Wilson <George.Wilson@Sun.COM>
parents: 8241
diff changeset
   215
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   216
	sm->sm_space -= size;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   217
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   218
13973
4972ab336f54 3464 zfs synctask code needs restructuring
Matthew Ahrens <mahrens@delphix.com>
parents: 13959
diff changeset
   219
space_seg_t *
4972ab336f54 3464 zfs synctask code needs restructuring
Matthew Ahrens <mahrens@delphix.com>
parents: 13959
diff changeset
   220
space_map_find(space_map_t *sm, uint64_t start, uint64_t size,
4972ab336f54 3464 zfs synctask code needs restructuring
Matthew Ahrens <mahrens@delphix.com>
parents: 13959
diff changeset
   221
    avl_index_t *wherep)
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   222
{
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   223
	space_seg_t ssearch, *ss;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   224
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   225
	ASSERT(MUTEX_HELD(sm->sm_lock));
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   226
	VERIFY(size != 0);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   227
	VERIFY(P2PHASE(start, 1ULL << sm->sm_shift) == 0);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   228
	VERIFY(P2PHASE(size, 1ULL << sm->sm_shift) == 0);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   229
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   230
	ssearch.ss_start = start;
13973
4972ab336f54 3464 zfs synctask code needs restructuring
Matthew Ahrens <mahrens@delphix.com>
parents: 13959
diff changeset
   231
	ssearch.ss_end = start + size;
4972ab336f54 3464 zfs synctask code needs restructuring
Matthew Ahrens <mahrens@delphix.com>
parents: 13959
diff changeset
   232
	ss = avl_find(&sm->sm_root, &ssearch, wherep);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   233
13973
4972ab336f54 3464 zfs synctask code needs restructuring
Matthew Ahrens <mahrens@delphix.com>
parents: 13959
diff changeset
   234
	if (ss != NULL && ss->ss_start <= start && ss->ss_end >= start + size)
4972ab336f54 3464 zfs synctask code needs restructuring
Matthew Ahrens <mahrens@delphix.com>
parents: 13959
diff changeset
   235
		return (ss);
4972ab336f54 3464 zfs synctask code needs restructuring
Matthew Ahrens <mahrens@delphix.com>
parents: 13959
diff changeset
   236
	return (NULL);
4972ab336f54 3464 zfs synctask code needs restructuring
Matthew Ahrens <mahrens@delphix.com>
parents: 13959
diff changeset
   237
}
4972ab336f54 3464 zfs synctask code needs restructuring
Matthew Ahrens <mahrens@delphix.com>
parents: 13959
diff changeset
   238
4972ab336f54 3464 zfs synctask code needs restructuring
Matthew Ahrens <mahrens@delphix.com>
parents: 13959
diff changeset
   239
boolean_t
4972ab336f54 3464 zfs synctask code needs restructuring
Matthew Ahrens <mahrens@delphix.com>
parents: 13959
diff changeset
   240
space_map_contains(space_map_t *sm, uint64_t start, uint64_t size)
4972ab336f54 3464 zfs synctask code needs restructuring
Matthew Ahrens <mahrens@delphix.com>
parents: 13959
diff changeset
   241
{
4972ab336f54 3464 zfs synctask code needs restructuring
Matthew Ahrens <mahrens@delphix.com>
parents: 13959
diff changeset
   242
	avl_index_t where;
4972ab336f54 3464 zfs synctask code needs restructuring
Matthew Ahrens <mahrens@delphix.com>
parents: 13959
diff changeset
   243
4972ab336f54 3464 zfs synctask code needs restructuring
Matthew Ahrens <mahrens@delphix.com>
parents: 13959
diff changeset
   244
	return (space_map_find(sm, start, size, &where) != 0);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   245
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   246
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   247
void
13959
e03e14ddfb4c 3552 condensing one space map burns 3 seconds of CPU in spa_sync() thread
George Wilson <george.wilson@delphix.com>
parents: 13879
diff changeset
   248
space_map_swap(space_map_t **msrc, space_map_t **mdst)
e03e14ddfb4c 3552 condensing one space map burns 3 seconds of CPU in spa_sync() thread
George Wilson <george.wilson@delphix.com>
parents: 13879
diff changeset
   249
{
e03e14ddfb4c 3552 condensing one space map burns 3 seconds of CPU in spa_sync() thread
George Wilson <george.wilson@delphix.com>
parents: 13879
diff changeset
   250
	space_map_t *sm;
e03e14ddfb4c 3552 condensing one space map burns 3 seconds of CPU in spa_sync() thread
George Wilson <george.wilson@delphix.com>
parents: 13879
diff changeset
   251
e03e14ddfb4c 3552 condensing one space map burns 3 seconds of CPU in spa_sync() thread
George Wilson <george.wilson@delphix.com>
parents: 13879
diff changeset
   252
	ASSERT(MUTEX_HELD((*msrc)->sm_lock));
e03e14ddfb4c 3552 condensing one space map burns 3 seconds of CPU in spa_sync() thread
George Wilson <george.wilson@delphix.com>
parents: 13879
diff changeset
   253
	ASSERT0((*mdst)->sm_space);
e03e14ddfb4c 3552 condensing one space map burns 3 seconds of CPU in spa_sync() thread
George Wilson <george.wilson@delphix.com>
parents: 13879
diff changeset
   254
	ASSERT0(avl_numnodes(&(*mdst)->sm_root));
e03e14ddfb4c 3552 condensing one space map burns 3 seconds of CPU in spa_sync() thread
George Wilson <george.wilson@delphix.com>
parents: 13879
diff changeset
   255
e03e14ddfb4c 3552 condensing one space map burns 3 seconds of CPU in spa_sync() thread
George Wilson <george.wilson@delphix.com>
parents: 13879
diff changeset
   256
	sm = *msrc;
e03e14ddfb4c 3552 condensing one space map burns 3 seconds of CPU in spa_sync() thread
George Wilson <george.wilson@delphix.com>
parents: 13879
diff changeset
   257
	*msrc = *mdst;
e03e14ddfb4c 3552 condensing one space map burns 3 seconds of CPU in spa_sync() thread
George Wilson <george.wilson@delphix.com>
parents: 13879
diff changeset
   258
	*mdst = sm;
e03e14ddfb4c 3552 condensing one space map burns 3 seconds of CPU in spa_sync() thread
George Wilson <george.wilson@delphix.com>
parents: 13879
diff changeset
   259
}
e03e14ddfb4c 3552 condensing one space map burns 3 seconds of CPU in spa_sync() thread
George Wilson <george.wilson@delphix.com>
parents: 13879
diff changeset
   260
e03e14ddfb4c 3552 condensing one space map burns 3 seconds of CPU in spa_sync() thread
George Wilson <george.wilson@delphix.com>
parents: 13879
diff changeset
   261
void
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   262
space_map_vacate(space_map_t *sm, space_map_func_t *func, space_map_t *mdest)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   263
{
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   264
	space_seg_t *ss;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   265
	void *cookie = NULL;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   266
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   267
	ASSERT(MUTEX_HELD(sm->sm_lock));
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   268
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   269
	while ((ss = avl_destroy_nodes(&sm->sm_root, &cookie)) != NULL) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   270
		if (func != NULL)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   271
			func(mdest, ss->ss_start, ss->ss_end - ss->ss_start);
13879
4eac7a87eff2 3329 spa_sync() spends 10-20% of its time in spa_free_sync_cb()
George Wilson <george.wilson@delphix.com>
parents: 13805
diff changeset
   272
		kmem_cache_free(space_seg_cache, ss);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   273
	}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   274
	sm->sm_space = 0;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   275
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   276
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   277
void
1732
9e3ae798af31 6280668 pluggable block allocation policy
bonwick
parents: 1544
diff changeset
   278
space_map_walk(space_map_t *sm, space_map_func_t *func, space_map_t *mdest)
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   279
{
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   280
	space_seg_t *ss;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   281
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   282
	ASSERT(MUTEX_HELD(sm->sm_lock));
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   283
8241
5a60f16123ba 6328632 zpool offline is a bit too conservative
Jeff Bonwick <Jeff.Bonwick@Sun.COM>
parents: 8214
diff changeset
   284
	for (ss = avl_first(&sm->sm_root); ss; ss = AVL_NEXT(&sm->sm_root, ss))
5a60f16123ba 6328632 zpool offline is a bit too conservative
Jeff Bonwick <Jeff.Bonwick@Sun.COM>
parents: 8214
diff changeset
   285
		func(mdest, ss->ss_start, ss->ss_end - ss->ss_start);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   286
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   287
1732
9e3ae798af31 6280668 pluggable block allocation policy
bonwick
parents: 1544
diff changeset
   288
/*
9e3ae798af31 6280668 pluggable block allocation policy
bonwick
parents: 1544
diff changeset
   289
 * Wait for any in-progress space_map_load() to complete.
9e3ae798af31 6280668 pluggable block allocation policy
bonwick
parents: 1544
diff changeset
   290
 */
9e3ae798af31 6280668 pluggable block allocation policy
bonwick
parents: 1544
diff changeset
   291
void
9e3ae798af31 6280668 pluggable block allocation policy
bonwick
parents: 1544
diff changeset
   292
space_map_load_wait(space_map_t *sm)
9e3ae798af31 6280668 pluggable block allocation policy
bonwick
parents: 1544
diff changeset
   293
{
9e3ae798af31 6280668 pluggable block allocation policy
bonwick
parents: 1544
diff changeset
   294
	ASSERT(MUTEX_HELD(sm->sm_lock));
9e3ae798af31 6280668 pluggable block allocation policy
bonwick
parents: 1544
diff changeset
   295
10922
e2081f502306 PSARC 2009/571 ZFS Deduplication Properties
Jeff Bonwick <Jeff.Bonwick@Sun.COM>
parents: 10921
diff changeset
   296
	while (sm->sm_loading) {
e2081f502306 PSARC 2009/571 ZFS Deduplication Properties
Jeff Bonwick <Jeff.Bonwick@Sun.COM>
parents: 10921
diff changeset
   297
		ASSERT(!sm->sm_loaded);
1732
9e3ae798af31 6280668 pluggable block allocation policy
bonwick
parents: 1544
diff changeset
   298
		cv_wait(&sm->sm_load_cv, sm->sm_lock);
10922
e2081f502306 PSARC 2009/571 ZFS Deduplication Properties
Jeff Bonwick <Jeff.Bonwick@Sun.COM>
parents: 10921
diff changeset
   299
	}
1732
9e3ae798af31 6280668 pluggable block allocation policy
bonwick
parents: 1544
diff changeset
   300
}
9e3ae798af31 6280668 pluggable block allocation policy
bonwick
parents: 1544
diff changeset
   301
9e3ae798af31 6280668 pluggable block allocation policy
bonwick
parents: 1544
diff changeset
   302
/*
9e3ae798af31 6280668 pluggable block allocation policy
bonwick
parents: 1544
diff changeset
   303
 * Note: space_map_load() will drop sm_lock across dmu_read() calls.
9e3ae798af31 6280668 pluggable block allocation policy
bonwick
parents: 1544
diff changeset
   304
 * The caller must be OK with this.
9e3ae798af31 6280668 pluggable block allocation policy
bonwick
parents: 1544
diff changeset
   305
 */
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   306
int
1732
9e3ae798af31 6280668 pluggable block allocation policy
bonwick
parents: 1544
diff changeset
   307
space_map_load(space_map_t *sm, space_map_ops_t *ops, uint8_t maptype,
9e3ae798af31 6280668 pluggable block allocation policy
bonwick
parents: 1544
diff changeset
   308
	space_map_obj_t *smo, objset_t *os)
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   309
{
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   310
	uint64_t *entry, *entry_map, *entry_map_end;
3761
f5abe2a41b3e 6458218 assertion failed: ss == NULL
billm
parents: 3713
diff changeset
   311
	uint64_t bufsize, size, offset, end, space;
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   312
	uint64_t mapstart = sm->sm_start;
5329
33cb98223b2d PSARC 2007/567 zpool failmode property
gw25295
parents: 3761
diff changeset
   313
	int error = 0;
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   314
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   315
	ASSERT(MUTEX_HELD(sm->sm_lock));
10921
8aac17999e4d PSARC 2009/479 zpool recovery support
Tim Haley <Tim.Haley@Sun.COM>
parents: 9574
diff changeset
   316
	ASSERT(!sm->sm_loaded);
8aac17999e4d PSARC 2009/479 zpool recovery support
Tim Haley <Tim.Haley@Sun.COM>
parents: 9574
diff changeset
   317
	ASSERT(!sm->sm_loading);
1732
9e3ae798af31 6280668 pluggable block allocation policy
bonwick
parents: 1544
diff changeset
   318
9e3ae798af31 6280668 pluggable block allocation policy
bonwick
parents: 1544
diff changeset
   319
	sm->sm_loading = B_TRUE;
3761
f5abe2a41b3e 6458218 assertion failed: ss == NULL
billm
parents: 3713
diff changeset
   320
	end = smo->smo_objsize;
f5abe2a41b3e 6458218 assertion failed: ss == NULL
billm
parents: 3713
diff changeset
   321
	space = smo->smo_alloc;
1732
9e3ae798af31 6280668 pluggable block allocation policy
bonwick
parents: 1544
diff changeset
   322
9e3ae798af31 6280668 pluggable block allocation policy
bonwick
parents: 1544
diff changeset
   323
	ASSERT(sm->sm_ops == NULL);
13805
e3a9ae14a119 3006 VERIFY[S,U,P] and ASSERT[S,U,P] frequently check if first argument is zero
Madhav Suresh <madhav.suresh@delphix.com>
parents: 13765
diff changeset
   324
	VERIFY0(sm->sm_space);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   325
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   326
	if (maptype == SM_FREE) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   327
		space_map_add(sm, sm->sm_start, sm->sm_size);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   328
		space = sm->sm_size - space;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   329
	}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   330
1732
9e3ae798af31 6280668 pluggable block allocation policy
bonwick
parents: 1544
diff changeset
   331
	bufsize = 1ULL << SPACE_MAP_BLOCKSHIFT;
9e3ae798af31 6280668 pluggable block allocation policy
bonwick
parents: 1544
diff changeset
   332
	entry_map = zio_buf_alloc(bufsize);
9e3ae798af31 6280668 pluggable block allocation policy
bonwick
parents: 1544
diff changeset
   333
9e3ae798af31 6280668 pluggable block allocation policy
bonwick
parents: 1544
diff changeset
   334
	mutex_exit(sm->sm_lock);
9e3ae798af31 6280668 pluggable block allocation policy
bonwick
parents: 1544
diff changeset
   335
	if (end > bufsize)
9e3ae798af31 6280668 pluggable block allocation policy
bonwick
parents: 1544
diff changeset
   336
		dmu_prefetch(os, smo->smo_object, bufsize, end - bufsize);
9e3ae798af31 6280668 pluggable block allocation policy
bonwick
parents: 1544
diff changeset
   337
	mutex_enter(sm->sm_lock);
9e3ae798af31 6280668 pluggable block allocation policy
bonwick
parents: 1544
diff changeset
   338
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   339
	for (offset = 0; offset < end; offset += bufsize) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   340
		size = MIN(end - offset, bufsize);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   341
		VERIFY(P2PHASE(size, sizeof (uint64_t)) == 0);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   342
		VERIFY(size != 0);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   343
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   344
		dprintf("object=%llu  offset=%llx  size=%llx\n",
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   345
		    smo->smo_object, offset, size);
1732
9e3ae798af31 6280668 pluggable block allocation policy
bonwick
parents: 1544
diff changeset
   346
9e3ae798af31 6280668 pluggable block allocation policy
bonwick
parents: 1544
diff changeset
   347
		mutex_exit(sm->sm_lock);
9512
64cafcbcc337 6801810 Commit of aligned streaming rewrites to ZIL device causes unwanted disk reads
Neil Perrin <Neil.Perrin@Sun.COM>
parents: 9480
diff changeset
   348
		error = dmu_read(os, smo->smo_object, offset, size, entry_map,
64cafcbcc337 6801810 Commit of aligned streaming rewrites to ZIL device causes unwanted disk reads
Neil Perrin <Neil.Perrin@Sun.COM>
parents: 9480
diff changeset
   349
		    DMU_READ_PREFETCH);
1732
9e3ae798af31 6280668 pluggable block allocation policy
bonwick
parents: 1544
diff changeset
   350
		mutex_enter(sm->sm_lock);
5329
33cb98223b2d PSARC 2007/567 zpool failmode property
gw25295
parents: 3761
diff changeset
   351
		if (error != 0)
6227
4d8365755b7b 6657693 assertion failed: sm->sm_space == 0 (0x1000000000 == 0x0)
vl146290
parents: 5329
diff changeset
   352
			break;
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   353
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   354
		entry_map_end = entry_map + (size / sizeof (uint64_t));
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   355
		for (entry = entry_map; entry < entry_map_end; entry++) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   356
			uint64_t e = *entry;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   357
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   358
			if (SM_DEBUG_DECODE(e))		/* Skip debug entries */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   359
				continue;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   360
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   361
			(SM_TYPE_DECODE(e) == maptype ?
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   362
			    space_map_add : space_map_remove)(sm,
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   363
			    (SM_OFFSET_DECODE(e) << sm->sm_shift) + mapstart,
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   364
			    SM_RUN_DECODE(e) << sm->sm_shift);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   365
		}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   366
	}
6227
4d8365755b7b 6657693 assertion failed: sm->sm_space == 0 (0x1000000000 == 0x0)
vl146290
parents: 5329
diff changeset
   367
4d8365755b7b 6657693 assertion failed: sm->sm_space == 0 (0x1000000000 == 0x0)
vl146290
parents: 5329
diff changeset
   368
	if (error == 0) {
4d8365755b7b 6657693 assertion failed: sm->sm_space == 0 (0x1000000000 == 0x0)
vl146290
parents: 5329
diff changeset
   369
		VERIFY3U(sm->sm_space, ==, space);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   370
6227
4d8365755b7b 6657693 assertion failed: sm->sm_space == 0 (0x1000000000 == 0x0)
vl146290
parents: 5329
diff changeset
   371
		sm->sm_loaded = B_TRUE;
4d8365755b7b 6657693 assertion failed: sm->sm_space == 0 (0x1000000000 == 0x0)
vl146290
parents: 5329
diff changeset
   372
		sm->sm_ops = ops;
4d8365755b7b 6657693 assertion failed: sm->sm_space == 0 (0x1000000000 == 0x0)
vl146290
parents: 5329
diff changeset
   373
		if (ops != NULL)
4d8365755b7b 6657693 assertion failed: sm->sm_space == 0 (0x1000000000 == 0x0)
vl146290
parents: 5329
diff changeset
   374
			ops->smop_load(sm);
4d8365755b7b 6657693 assertion failed: sm->sm_space == 0 (0x1000000000 == 0x0)
vl146290
parents: 5329
diff changeset
   375
	} else {
4d8365755b7b 6657693 assertion failed: sm->sm_space == 0 (0x1000000000 == 0x0)
vl146290
parents: 5329
diff changeset
   376
		space_map_vacate(sm, NULL, NULL);
4d8365755b7b 6657693 assertion failed: sm->sm_space == 0 (0x1000000000 == 0x0)
vl146290
parents: 5329
diff changeset
   377
	}
4d8365755b7b 6657693 assertion failed: sm->sm_space == 0 (0x1000000000 == 0x0)
vl146290
parents: 5329
diff changeset
   378
1732
9e3ae798af31 6280668 pluggable block allocation policy
bonwick
parents: 1544
diff changeset
   379
	zio_buf_free(entry_map, bufsize);
9e3ae798af31 6280668 pluggable block allocation policy
bonwick
parents: 1544
diff changeset
   380
9e3ae798af31 6280668 pluggable block allocation policy
bonwick
parents: 1544
diff changeset
   381
	sm->sm_loading = B_FALSE;
9e3ae798af31 6280668 pluggable block allocation policy
bonwick
parents: 1544
diff changeset
   382
9e3ae798af31 6280668 pluggable block allocation policy
bonwick
parents: 1544
diff changeset
   383
	cv_broadcast(&sm->sm_load_cv);
9e3ae798af31 6280668 pluggable block allocation policy
bonwick
parents: 1544
diff changeset
   384
5329
33cb98223b2d PSARC 2007/567 zpool failmode property
gw25295
parents: 3761
diff changeset
   385
	return (error);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   386
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   387
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   388
void
1732
9e3ae798af31 6280668 pluggable block allocation policy
bonwick
parents: 1544
diff changeset
   389
space_map_unload(space_map_t *sm)
9e3ae798af31 6280668 pluggable block allocation policy
bonwick
parents: 1544
diff changeset
   390
{
9e3ae798af31 6280668 pluggable block allocation policy
bonwick
parents: 1544
diff changeset
   391
	ASSERT(MUTEX_HELD(sm->sm_lock));
9e3ae798af31 6280668 pluggable block allocation policy
bonwick
parents: 1544
diff changeset
   392
9e3ae798af31 6280668 pluggable block allocation policy
bonwick
parents: 1544
diff changeset
   393
	if (sm->sm_loaded && sm->sm_ops != NULL)
9e3ae798af31 6280668 pluggable block allocation policy
bonwick
parents: 1544
diff changeset
   394
		sm->sm_ops->smop_unload(sm);
9e3ae798af31 6280668 pluggable block allocation policy
bonwick
parents: 1544
diff changeset
   395
9e3ae798af31 6280668 pluggable block allocation policy
bonwick
parents: 1544
diff changeset
   396
	sm->sm_loaded = B_FALSE;
9e3ae798af31 6280668 pluggable block allocation policy
bonwick
parents: 1544
diff changeset
   397
	sm->sm_ops = NULL;
9e3ae798af31 6280668 pluggable block allocation policy
bonwick
parents: 1544
diff changeset
   398
9e3ae798af31 6280668 pluggable block allocation policy
bonwick
parents: 1544
diff changeset
   399
	space_map_vacate(sm, NULL, NULL);
9e3ae798af31 6280668 pluggable block allocation policy
bonwick
parents: 1544
diff changeset
   400
}
9e3ae798af31 6280668 pluggable block allocation policy
bonwick
parents: 1544
diff changeset
   401
9e3ae798af31 6280668 pluggable block allocation policy
bonwick
parents: 1544
diff changeset
   402
uint64_t
9480
fcff33da767f 6596237 Stop looking and start ganging
George Wilson <George.Wilson@Sun.COM>
parents: 8241
diff changeset
   403
space_map_maxsize(space_map_t *sm)
fcff33da767f 6596237 Stop looking and start ganging
George Wilson <George.Wilson@Sun.COM>
parents: 8241
diff changeset
   404
{
11146
7e58f40bcb1c 6826241 Sync write IOPS drops dramatically during TXG sync
George Wilson <George.Wilson@Sun.COM>
parents: 10922
diff changeset
   405
	ASSERT(sm->sm_ops != NULL);
7e58f40bcb1c 6826241 Sync write IOPS drops dramatically during TXG sync
George Wilson <George.Wilson@Sun.COM>
parents: 10922
diff changeset
   406
	return (sm->sm_ops->smop_max(sm));
9480
fcff33da767f 6596237 Stop looking and start ganging
George Wilson <George.Wilson@Sun.COM>
parents: 8241
diff changeset
   407
}
fcff33da767f 6596237 Stop looking and start ganging
George Wilson <George.Wilson@Sun.COM>
parents: 8241
diff changeset
   408
fcff33da767f 6596237 Stop looking and start ganging
George Wilson <George.Wilson@Sun.COM>
parents: 8241
diff changeset
   409
uint64_t
1732
9e3ae798af31 6280668 pluggable block allocation policy
bonwick
parents: 1544
diff changeset
   410
space_map_alloc(space_map_t *sm, uint64_t size)
9e3ae798af31 6280668 pluggable block allocation policy
bonwick
parents: 1544
diff changeset
   411
{
9e3ae798af31 6280668 pluggable block allocation policy
bonwick
parents: 1544
diff changeset
   412
	uint64_t start;
9e3ae798af31 6280668 pluggable block allocation policy
bonwick
parents: 1544
diff changeset
   413
9e3ae798af31 6280668 pluggable block allocation policy
bonwick
parents: 1544
diff changeset
   414
	start = sm->sm_ops->smop_alloc(sm, size);
9e3ae798af31 6280668 pluggable block allocation policy
bonwick
parents: 1544
diff changeset
   415
	if (start != -1ULL)
9e3ae798af31 6280668 pluggable block allocation policy
bonwick
parents: 1544
diff changeset
   416
		space_map_remove(sm, start, size);
9e3ae798af31 6280668 pluggable block allocation policy
bonwick
parents: 1544
diff changeset
   417
	return (start);
9e3ae798af31 6280668 pluggable block allocation policy
bonwick
parents: 1544
diff changeset
   418
}
9e3ae798af31 6280668 pluggable block allocation policy
bonwick
parents: 1544
diff changeset
   419
9e3ae798af31 6280668 pluggable block allocation policy
bonwick
parents: 1544
diff changeset
   420
void
9e3ae798af31 6280668 pluggable block allocation policy
bonwick
parents: 1544
diff changeset
   421
space_map_claim(space_map_t *sm, uint64_t start, uint64_t size)
9e3ae798af31 6280668 pluggable block allocation policy
bonwick
parents: 1544
diff changeset
   422
{
9e3ae798af31 6280668 pluggable block allocation policy
bonwick
parents: 1544
diff changeset
   423
	sm->sm_ops->smop_claim(sm, start, size);
9e3ae798af31 6280668 pluggable block allocation policy
bonwick
parents: 1544
diff changeset
   424
	space_map_remove(sm, start, size);
9e3ae798af31 6280668 pluggable block allocation policy
bonwick
parents: 1544
diff changeset
   425
}
9e3ae798af31 6280668 pluggable block allocation policy
bonwick
parents: 1544
diff changeset
   426
9e3ae798af31 6280668 pluggable block allocation policy
bonwick
parents: 1544
diff changeset
   427
void
9e3ae798af31 6280668 pluggable block allocation policy
bonwick
parents: 1544
diff changeset
   428
space_map_free(space_map_t *sm, uint64_t start, uint64_t size)
9e3ae798af31 6280668 pluggable block allocation policy
bonwick
parents: 1544
diff changeset
   429
{
9e3ae798af31 6280668 pluggable block allocation policy
bonwick
parents: 1544
diff changeset
   430
	space_map_add(sm, start, size);
9e3ae798af31 6280668 pluggable block allocation policy
bonwick
parents: 1544
diff changeset
   431
	sm->sm_ops->smop_free(sm, start, size);
9e3ae798af31 6280668 pluggable block allocation policy
bonwick
parents: 1544
diff changeset
   432
}
9e3ae798af31 6280668 pluggable block allocation policy
bonwick
parents: 1544
diff changeset
   433
9e3ae798af31 6280668 pluggable block allocation policy
bonwick
parents: 1544
diff changeset
   434
/*
9e3ae798af31 6280668 pluggable block allocation policy
bonwick
parents: 1544
diff changeset
   435
 * Note: space_map_sync() will drop sm_lock across dmu_write() calls.
9e3ae798af31 6280668 pluggable block allocation policy
bonwick
parents: 1544
diff changeset
   436
 */
9e3ae798af31 6280668 pluggable block allocation policy
bonwick
parents: 1544
diff changeset
   437
void
9e3ae798af31 6280668 pluggable block allocation policy
bonwick
parents: 1544
diff changeset
   438
space_map_sync(space_map_t *sm, uint8_t maptype,
9e3ae798af31 6280668 pluggable block allocation policy
bonwick
parents: 1544
diff changeset
   439
	space_map_obj_t *smo, objset_t *os, dmu_tx_t *tx)
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   440
{
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   441
	spa_t *spa = dmu_objset_spa(os);
13959
e03e14ddfb4c 3552 condensing one space map burns 3 seconds of CPU in spa_sync() thread
George Wilson <george.wilson@delphix.com>
parents: 13879
diff changeset
   442
	avl_tree_t *t = &sm->sm_root;
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   443
	space_seg_t *ss;
13959
e03e14ddfb4c 3552 condensing one space map burns 3 seconds of CPU in spa_sync() thread
George Wilson <george.wilson@delphix.com>
parents: 13879
diff changeset
   444
	uint64_t bufsize, start, size, run_len, total, sm_space, nodes;
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   445
	uint64_t *entry, *entry_map, *entry_map_end;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   446
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   447
	ASSERT(MUTEX_HELD(sm->sm_lock));
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   448
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   449
	if (sm->sm_space == 0)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   450
		return;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   451
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   452
	dprintf("object %4llu, txg %llu, pass %d, %c, count %lu, space %llx\n",
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   453
	    smo->smo_object, dmu_tx_get_txg(tx), spa_sync_pass(spa),
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   454
	    maptype == SM_ALLOC ? 'A' : 'F', avl_numnodes(&sm->sm_root),
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   455
	    sm->sm_space);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   456
1732
9e3ae798af31 6280668 pluggable block allocation policy
bonwick
parents: 1544
diff changeset
   457
	if (maptype == SM_ALLOC)
9e3ae798af31 6280668 pluggable block allocation policy
bonwick
parents: 1544
diff changeset
   458
		smo->smo_alloc += sm->sm_space;
9e3ae798af31 6280668 pluggable block allocation policy
bonwick
parents: 1544
diff changeset
   459
	else
9e3ae798af31 6280668 pluggable block allocation policy
bonwick
parents: 1544
diff changeset
   460
		smo->smo_alloc -= sm->sm_space;
9e3ae798af31 6280668 pluggable block allocation policy
bonwick
parents: 1544
diff changeset
   461
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   462
	bufsize = (8 + avl_numnodes(&sm->sm_root)) * sizeof (uint64_t);
1732
9e3ae798af31 6280668 pluggable block allocation policy
bonwick
parents: 1544
diff changeset
   463
	bufsize = MIN(bufsize, 1ULL << SPACE_MAP_BLOCKSHIFT);
9e3ae798af31 6280668 pluggable block allocation policy
bonwick
parents: 1544
diff changeset
   464
	entry_map = zio_buf_alloc(bufsize);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   465
	entry_map_end = entry_map + (bufsize / sizeof (uint64_t));
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   466
	entry = entry_map;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   467
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   468
	*entry++ = SM_DEBUG_ENCODE(1) |
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   469
	    SM_DEBUG_ACTION_ENCODE(maptype) |
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   470
	    SM_DEBUG_SYNCPASS_ENCODE(spa_sync_pass(spa)) |
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   471
	    SM_DEBUG_TXG_ENCODE(dmu_tx_get_txg(tx));
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   472
13959
e03e14ddfb4c 3552 condensing one space map burns 3 seconds of CPU in spa_sync() thread
George Wilson <george.wilson@delphix.com>
parents: 13879
diff changeset
   473
	total = 0;
e03e14ddfb4c 3552 condensing one space map burns 3 seconds of CPU in spa_sync() thread
George Wilson <george.wilson@delphix.com>
parents: 13879
diff changeset
   474
	nodes = avl_numnodes(&sm->sm_root);
13879
4eac7a87eff2 3329 spa_sync() spends 10-20% of its time in spa_free_sync_cb()
George Wilson <george.wilson@delphix.com>
parents: 13805
diff changeset
   475
	sm_space = sm->sm_space;
13959
e03e14ddfb4c 3552 condensing one space map burns 3 seconds of CPU in spa_sync() thread
George Wilson <george.wilson@delphix.com>
parents: 13879
diff changeset
   476
	for (ss = avl_first(t); ss != NULL; ss = AVL_NEXT(t, ss)) {
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   477
		size = ss->ss_end - ss->ss_start;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   478
		start = (ss->ss_start - sm->sm_start) >> sm->sm_shift;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   479
13959
e03e14ddfb4c 3552 condensing one space map burns 3 seconds of CPU in spa_sync() thread
George Wilson <george.wilson@delphix.com>
parents: 13879
diff changeset
   480
		total += size;
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   481
		size >>= sm->sm_shift;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   482
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   483
		while (size) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   484
			run_len = MIN(size, SM_RUN_MAX);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   485
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   486
			if (entry == entry_map_end) {
1732
9e3ae798af31 6280668 pluggable block allocation policy
bonwick
parents: 1544
diff changeset
   487
				mutex_exit(sm->sm_lock);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   488
				dmu_write(os, smo->smo_object, smo->smo_objsize,
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   489
				    bufsize, entry_map, tx);
1732
9e3ae798af31 6280668 pluggable block allocation policy
bonwick
parents: 1544
diff changeset
   490
				mutex_enter(sm->sm_lock);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   491
				smo->smo_objsize += bufsize;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   492
				entry = entry_map;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   493
			}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   494
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   495
			*entry++ = SM_OFFSET_ENCODE(start) |
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   496
			    SM_TYPE_ENCODE(maptype) |
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   497
			    SM_RUN_ENCODE(run_len);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   498
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   499
			start += run_len;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   500
			size -= run_len;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   501
		}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   502
	}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   503
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   504
	if (entry != entry_map) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   505
		size = (entry - entry_map) * sizeof (uint64_t);
1732
9e3ae798af31 6280668 pluggable block allocation policy
bonwick
parents: 1544
diff changeset
   506
		mutex_exit(sm->sm_lock);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   507
		dmu_write(os, smo->smo_object, smo->smo_objsize,
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   508
		    size, entry_map, tx);
1732
9e3ae798af31 6280668 pluggable block allocation policy
bonwick
parents: 1544
diff changeset
   509
		mutex_enter(sm->sm_lock);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   510
		smo->smo_objsize += size;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   511
	}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   512
13879
4eac7a87eff2 3329 spa_sync() spends 10-20% of its time in spa_free_sync_cb()
George Wilson <george.wilson@delphix.com>
parents: 13805
diff changeset
   513
	/*
4eac7a87eff2 3329 spa_sync() spends 10-20% of its time in spa_free_sync_cb()
George Wilson <george.wilson@delphix.com>
parents: 13805
diff changeset
   514
	 * Ensure that the space_map's accounting wasn't changed
4eac7a87eff2 3329 spa_sync() spends 10-20% of its time in spa_free_sync_cb()
George Wilson <george.wilson@delphix.com>
parents: 13805
diff changeset
   515
	 * while we were in the middle of writing it out.
4eac7a87eff2 3329 spa_sync() spends 10-20% of its time in spa_free_sync_cb()
George Wilson <george.wilson@delphix.com>
parents: 13805
diff changeset
   516
	 */
13959
e03e14ddfb4c 3552 condensing one space map burns 3 seconds of CPU in spa_sync() thread
George Wilson <george.wilson@delphix.com>
parents: 13879
diff changeset
   517
	VERIFY3U(nodes, ==, avl_numnodes(&sm->sm_root));
13879
4eac7a87eff2 3329 spa_sync() spends 10-20% of its time in spa_free_sync_cb()
George Wilson <george.wilson@delphix.com>
parents: 13805
diff changeset
   518
	VERIFY3U(sm->sm_space, ==, sm_space);
13959
e03e14ddfb4c 3552 condensing one space map burns 3 seconds of CPU in spa_sync() thread
George Wilson <george.wilson@delphix.com>
parents: 13879
diff changeset
   519
	VERIFY3U(sm->sm_space, ==, total);
13879
4eac7a87eff2 3329 spa_sync() spends 10-20% of its time in spa_free_sync_cb()
George Wilson <george.wilson@delphix.com>
parents: 13805
diff changeset
   520
1732
9e3ae798af31 6280668 pluggable block allocation policy
bonwick
parents: 1544
diff changeset
   521
	zio_buf_free(entry_map, bufsize);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   522
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   523
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   524
void
1732
9e3ae798af31 6280668 pluggable block allocation policy
bonwick
parents: 1544
diff changeset
   525
space_map_truncate(space_map_obj_t *smo, objset_t *os, dmu_tx_t *tx)
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   526
{
1732
9e3ae798af31 6280668 pluggable block allocation policy
bonwick
parents: 1544
diff changeset
   527
	VERIFY(dmu_free_range(os, smo->smo_object, 0, -1ULL, tx) == 0);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   528
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   529
	smo->smo_objsize = 0;
1732
9e3ae798af31 6280668 pluggable block allocation policy
bonwick
parents: 1544
diff changeset
   530
	smo->smo_alloc = 0;
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   531
}
8241
5a60f16123ba 6328632 zpool offline is a bit too conservative
Jeff Bonwick <Jeff.Bonwick@Sun.COM>
parents: 8214
diff changeset
   532
5a60f16123ba 6328632 zpool offline is a bit too conservative
Jeff Bonwick <Jeff.Bonwick@Sun.COM>
parents: 8214
diff changeset
   533
/*
5a60f16123ba 6328632 zpool offline is a bit too conservative
Jeff Bonwick <Jeff.Bonwick@Sun.COM>
parents: 8214
diff changeset
   534
 * Space map reference trees.
5a60f16123ba 6328632 zpool offline is a bit too conservative
Jeff Bonwick <Jeff.Bonwick@Sun.COM>
parents: 8214
diff changeset
   535
 *
5a60f16123ba 6328632 zpool offline is a bit too conservative
Jeff Bonwick <Jeff.Bonwick@Sun.COM>
parents: 8214
diff changeset
   536
 * A space map is a collection of integers.  Every integer is either
5a60f16123ba 6328632 zpool offline is a bit too conservative
Jeff Bonwick <Jeff.Bonwick@Sun.COM>
parents: 8214
diff changeset
   537
 * in the map, or it's not.  A space map reference tree generalizes
5a60f16123ba 6328632 zpool offline is a bit too conservative
Jeff Bonwick <Jeff.Bonwick@Sun.COM>
parents: 8214
diff changeset
   538
 * the idea: it allows its members to have arbitrary reference counts,
5a60f16123ba 6328632 zpool offline is a bit too conservative
Jeff Bonwick <Jeff.Bonwick@Sun.COM>
parents: 8214
diff changeset
   539
 * as opposed to the implicit reference count of 0 or 1 in a space map.
5a60f16123ba 6328632 zpool offline is a bit too conservative
Jeff Bonwick <Jeff.Bonwick@Sun.COM>
parents: 8214
diff changeset
   540
 * This representation comes in handy when computing the union or
5a60f16123ba 6328632 zpool offline is a bit too conservative
Jeff Bonwick <Jeff.Bonwick@Sun.COM>
parents: 8214
diff changeset
   541
 * intersection of multiple space maps.  For example, the union of
5a60f16123ba 6328632 zpool offline is a bit too conservative
Jeff Bonwick <Jeff.Bonwick@Sun.COM>
parents: 8214
diff changeset
   542
 * N space maps is the subset of the reference tree with refcnt >= 1.
5a60f16123ba 6328632 zpool offline is a bit too conservative
Jeff Bonwick <Jeff.Bonwick@Sun.COM>
parents: 8214
diff changeset
   543
 * The intersection of N space maps is the subset with refcnt >= N.
5a60f16123ba 6328632 zpool offline is a bit too conservative
Jeff Bonwick <Jeff.Bonwick@Sun.COM>
parents: 8214
diff changeset
   544
 *
5a60f16123ba 6328632 zpool offline is a bit too conservative
Jeff Bonwick <Jeff.Bonwick@Sun.COM>
parents: 8214
diff changeset
   545
 * [It's very much like a Fourier transform.  Unions and intersections
5a60f16123ba 6328632 zpool offline is a bit too conservative
Jeff Bonwick <Jeff.Bonwick@Sun.COM>
parents: 8214
diff changeset
   546
 * are hard to perform in the 'space map domain', so we convert the maps
5a60f16123ba 6328632 zpool offline is a bit too conservative
Jeff Bonwick <Jeff.Bonwick@Sun.COM>
parents: 8214
diff changeset
   547
 * into the 'reference count domain', where it's trivial, then invert.]
5a60f16123ba 6328632 zpool offline is a bit too conservative
Jeff Bonwick <Jeff.Bonwick@Sun.COM>
parents: 8214
diff changeset
   548
 *
5a60f16123ba 6328632 zpool offline is a bit too conservative
Jeff Bonwick <Jeff.Bonwick@Sun.COM>
parents: 8214
diff changeset
   549
 * vdev_dtl_reassess() uses computations of this form to determine
5a60f16123ba 6328632 zpool offline is a bit too conservative
Jeff Bonwick <Jeff.Bonwick@Sun.COM>
parents: 8214
diff changeset
   550
 * DTL_MISSING and DTL_OUTAGE for interior vdevs -- e.g. a RAID-Z vdev
5a60f16123ba 6328632 zpool offline is a bit too conservative
Jeff Bonwick <Jeff.Bonwick@Sun.COM>
parents: 8214
diff changeset
   551
 * has an outage wherever refcnt >= vdev_nparity + 1, and a mirror vdev
5a60f16123ba 6328632 zpool offline is a bit too conservative
Jeff Bonwick <Jeff.Bonwick@Sun.COM>
parents: 8214
diff changeset
   552
 * has an outage wherever refcnt >= vdev_children.
5a60f16123ba 6328632 zpool offline is a bit too conservative
Jeff Bonwick <Jeff.Bonwick@Sun.COM>
parents: 8214
diff changeset
   553
 */
5a60f16123ba 6328632 zpool offline is a bit too conservative
Jeff Bonwick <Jeff.Bonwick@Sun.COM>
parents: 8214
diff changeset
   554
static int
5a60f16123ba 6328632 zpool offline is a bit too conservative
Jeff Bonwick <Jeff.Bonwick@Sun.COM>
parents: 8214
diff changeset
   555
space_map_ref_compare(const void *x1, const void *x2)
5a60f16123ba 6328632 zpool offline is a bit too conservative
Jeff Bonwick <Jeff.Bonwick@Sun.COM>
parents: 8214
diff changeset
   556
{
5a60f16123ba 6328632 zpool offline is a bit too conservative
Jeff Bonwick <Jeff.Bonwick@Sun.COM>
parents: 8214
diff changeset
   557
	const space_ref_t *sr1 = x1;
5a60f16123ba 6328632 zpool offline is a bit too conservative
Jeff Bonwick <Jeff.Bonwick@Sun.COM>
parents: 8214
diff changeset
   558
	const space_ref_t *sr2 = x2;
5a60f16123ba 6328632 zpool offline is a bit too conservative
Jeff Bonwick <Jeff.Bonwick@Sun.COM>
parents: 8214
diff changeset
   559
5a60f16123ba 6328632 zpool offline is a bit too conservative
Jeff Bonwick <Jeff.Bonwick@Sun.COM>
parents: 8214
diff changeset
   560
	if (sr1->sr_offset < sr2->sr_offset)
5a60f16123ba 6328632 zpool offline is a bit too conservative
Jeff Bonwick <Jeff.Bonwick@Sun.COM>
parents: 8214
diff changeset
   561
		return (-1);
5a60f16123ba 6328632 zpool offline is a bit too conservative
Jeff Bonwick <Jeff.Bonwick@Sun.COM>
parents: 8214
diff changeset
   562
	if (sr1->sr_offset > sr2->sr_offset)
5a60f16123ba 6328632 zpool offline is a bit too conservative
Jeff Bonwick <Jeff.Bonwick@Sun.COM>
parents: 8214
diff changeset
   563
		return (1);
5a60f16123ba 6328632 zpool offline is a bit too conservative
Jeff Bonwick <Jeff.Bonwick@Sun.COM>
parents: 8214
diff changeset
   564
5a60f16123ba 6328632 zpool offline is a bit too conservative
Jeff Bonwick <Jeff.Bonwick@Sun.COM>
parents: 8214
diff changeset
   565
	if (sr1 < sr2)
5a60f16123ba 6328632 zpool offline is a bit too conservative
Jeff Bonwick <Jeff.Bonwick@Sun.COM>
parents: 8214
diff changeset
   566
		return (-1);
5a60f16123ba 6328632 zpool offline is a bit too conservative
Jeff Bonwick <Jeff.Bonwick@Sun.COM>
parents: 8214
diff changeset
   567
	if (sr1 > sr2)
5a60f16123ba 6328632 zpool offline is a bit too conservative
Jeff Bonwick <Jeff.Bonwick@Sun.COM>
parents: 8214
diff changeset
   568
		return (1);
5a60f16123ba 6328632 zpool offline is a bit too conservative
Jeff Bonwick <Jeff.Bonwick@Sun.COM>
parents: 8214
diff changeset
   569
5a60f16123ba 6328632 zpool offline is a bit too conservative
Jeff Bonwick <Jeff.Bonwick@Sun.COM>
parents: 8214
diff changeset
   570
	return (0);
5a60f16123ba 6328632 zpool offline is a bit too conservative
Jeff Bonwick <Jeff.Bonwick@Sun.COM>
parents: 8214
diff changeset
   571
}
5a60f16123ba 6328632 zpool offline is a bit too conservative
Jeff Bonwick <Jeff.Bonwick@Sun.COM>
parents: 8214
diff changeset
   572
5a60f16123ba 6328632 zpool offline is a bit too conservative
Jeff Bonwick <Jeff.Bonwick@Sun.COM>
parents: 8214
diff changeset
   573
void
5a60f16123ba 6328632 zpool offline is a bit too conservative
Jeff Bonwick <Jeff.Bonwick@Sun.COM>
parents: 8214
diff changeset
   574
space_map_ref_create(avl_tree_t *t)
5a60f16123ba 6328632 zpool offline is a bit too conservative
Jeff Bonwick <Jeff.Bonwick@Sun.COM>
parents: 8214
diff changeset
   575
{
5a60f16123ba 6328632 zpool offline is a bit too conservative
Jeff Bonwick <Jeff.Bonwick@Sun.COM>
parents: 8214
diff changeset
   576
	avl_create(t, space_map_ref_compare,
5a60f16123ba 6328632 zpool offline is a bit too conservative
Jeff Bonwick <Jeff.Bonwick@Sun.COM>
parents: 8214
diff changeset
   577
	    sizeof (space_ref_t), offsetof(space_ref_t, sr_node));
5a60f16123ba 6328632 zpool offline is a bit too conservative
Jeff Bonwick <Jeff.Bonwick@Sun.COM>
parents: 8214
diff changeset
   578
}
5a60f16123ba 6328632 zpool offline is a bit too conservative
Jeff Bonwick <Jeff.Bonwick@Sun.COM>
parents: 8214
diff changeset
   579
5a60f16123ba 6328632 zpool offline is a bit too conservative
Jeff Bonwick <Jeff.Bonwick@Sun.COM>
parents: 8214
diff changeset
   580
void
5a60f16123ba 6328632 zpool offline is a bit too conservative
Jeff Bonwick <Jeff.Bonwick@Sun.COM>
parents: 8214
diff changeset
   581
space_map_ref_destroy(avl_tree_t *t)
5a60f16123ba 6328632 zpool offline is a bit too conservative
Jeff Bonwick <Jeff.Bonwick@Sun.COM>
parents: 8214
diff changeset
   582
{
5a60f16123ba 6328632 zpool offline is a bit too conservative
Jeff Bonwick <Jeff.Bonwick@Sun.COM>
parents: 8214
diff changeset
   583
	space_ref_t *sr;
5a60f16123ba 6328632 zpool offline is a bit too conservative
Jeff Bonwick <Jeff.Bonwick@Sun.COM>
parents: 8214
diff changeset
   584
	void *cookie = NULL;
5a60f16123ba 6328632 zpool offline is a bit too conservative
Jeff Bonwick <Jeff.Bonwick@Sun.COM>
parents: 8214
diff changeset
   585
5a60f16123ba 6328632 zpool offline is a bit too conservative
Jeff Bonwick <Jeff.Bonwick@Sun.COM>
parents: 8214
diff changeset
   586
	while ((sr = avl_destroy_nodes(t, &cookie)) != NULL)
5a60f16123ba 6328632 zpool offline is a bit too conservative
Jeff Bonwick <Jeff.Bonwick@Sun.COM>
parents: 8214
diff changeset
   587
		kmem_free(sr, sizeof (*sr));
5a60f16123ba 6328632 zpool offline is a bit too conservative
Jeff Bonwick <Jeff.Bonwick@Sun.COM>
parents: 8214
diff changeset
   588
5a60f16123ba 6328632 zpool offline is a bit too conservative
Jeff Bonwick <Jeff.Bonwick@Sun.COM>
parents: 8214
diff changeset
   589
	avl_destroy(t);
5a60f16123ba 6328632 zpool offline is a bit too conservative
Jeff Bonwick <Jeff.Bonwick@Sun.COM>
parents: 8214
diff changeset
   590
}
5a60f16123ba 6328632 zpool offline is a bit too conservative
Jeff Bonwick <Jeff.Bonwick@Sun.COM>
parents: 8214
diff changeset
   591
5a60f16123ba 6328632 zpool offline is a bit too conservative
Jeff Bonwick <Jeff.Bonwick@Sun.COM>
parents: 8214
diff changeset
   592
static void
5a60f16123ba 6328632 zpool offline is a bit too conservative
Jeff Bonwick <Jeff.Bonwick@Sun.COM>
parents: 8214
diff changeset
   593
space_map_ref_add_node(avl_tree_t *t, uint64_t offset, int64_t refcnt)
5a60f16123ba 6328632 zpool offline is a bit too conservative
Jeff Bonwick <Jeff.Bonwick@Sun.COM>
parents: 8214
diff changeset
   594
{
5a60f16123ba 6328632 zpool offline is a bit too conservative
Jeff Bonwick <Jeff.Bonwick@Sun.COM>
parents: 8214
diff changeset
   595
	space_ref_t *sr;
5a60f16123ba 6328632 zpool offline is a bit too conservative
Jeff Bonwick <Jeff.Bonwick@Sun.COM>
parents: 8214
diff changeset
   596
5a60f16123ba 6328632 zpool offline is a bit too conservative
Jeff Bonwick <Jeff.Bonwick@Sun.COM>
parents: 8214
diff changeset
   597
	sr = kmem_alloc(sizeof (*sr), KM_SLEEP);
5a60f16123ba 6328632 zpool offline is a bit too conservative
Jeff Bonwick <Jeff.Bonwick@Sun.COM>
parents: 8214
diff changeset
   598
	sr->sr_offset = offset;
5a60f16123ba 6328632 zpool offline is a bit too conservative
Jeff Bonwick <Jeff.Bonwick@Sun.COM>
parents: 8214
diff changeset
   599
	sr->sr_refcnt = refcnt;
5a60f16123ba 6328632 zpool offline is a bit too conservative
Jeff Bonwick <Jeff.Bonwick@Sun.COM>
parents: 8214
diff changeset
   600
5a60f16123ba 6328632 zpool offline is a bit too conservative
Jeff Bonwick <Jeff.Bonwick@Sun.COM>
parents: 8214
diff changeset
   601
	avl_add(t, sr);
5a60f16123ba 6328632 zpool offline is a bit too conservative
Jeff Bonwick <Jeff.Bonwick@Sun.COM>
parents: 8214
diff changeset
   602
}
5a60f16123ba 6328632 zpool offline is a bit too conservative
Jeff Bonwick <Jeff.Bonwick@Sun.COM>
parents: 8214
diff changeset
   603
5a60f16123ba 6328632 zpool offline is a bit too conservative
Jeff Bonwick <Jeff.Bonwick@Sun.COM>
parents: 8214
diff changeset
   604
void
5a60f16123ba 6328632 zpool offline is a bit too conservative
Jeff Bonwick <Jeff.Bonwick@Sun.COM>
parents: 8214
diff changeset
   605
space_map_ref_add_seg(avl_tree_t *t, uint64_t start, uint64_t end,
5a60f16123ba 6328632 zpool offline is a bit too conservative
Jeff Bonwick <Jeff.Bonwick@Sun.COM>
parents: 8214
diff changeset
   606
	int64_t refcnt)
5a60f16123ba 6328632 zpool offline is a bit too conservative
Jeff Bonwick <Jeff.Bonwick@Sun.COM>
parents: 8214
diff changeset
   607
{
5a60f16123ba 6328632 zpool offline is a bit too conservative
Jeff Bonwick <Jeff.Bonwick@Sun.COM>
parents: 8214
diff changeset
   608
	space_map_ref_add_node(t, start, refcnt);
5a60f16123ba 6328632 zpool offline is a bit too conservative
Jeff Bonwick <Jeff.Bonwick@Sun.COM>
parents: 8214
diff changeset
   609
	space_map_ref_add_node(t, end, -refcnt);
5a60f16123ba 6328632 zpool offline is a bit too conservative
Jeff Bonwick <Jeff.Bonwick@Sun.COM>
parents: 8214
diff changeset
   610
}
5a60f16123ba 6328632 zpool offline is a bit too conservative
Jeff Bonwick <Jeff.Bonwick@Sun.COM>
parents: 8214
diff changeset
   611
5a60f16123ba 6328632 zpool offline is a bit too conservative
Jeff Bonwick <Jeff.Bonwick@Sun.COM>
parents: 8214
diff changeset
   612
/*
5a60f16123ba 6328632 zpool offline is a bit too conservative
Jeff Bonwick <Jeff.Bonwick@Sun.COM>
parents: 8214
diff changeset
   613
 * Convert (or add) a space map into a reference tree.
5a60f16123ba 6328632 zpool offline is a bit too conservative
Jeff Bonwick <Jeff.Bonwick@Sun.COM>
parents: 8214
diff changeset
   614
 */
5a60f16123ba 6328632 zpool offline is a bit too conservative
Jeff Bonwick <Jeff.Bonwick@Sun.COM>
parents: 8214
diff changeset
   615
void
5a60f16123ba 6328632 zpool offline is a bit too conservative
Jeff Bonwick <Jeff.Bonwick@Sun.COM>
parents: 8214
diff changeset
   616
space_map_ref_add_map(avl_tree_t *t, space_map_t *sm, int64_t refcnt)
5a60f16123ba 6328632 zpool offline is a bit too conservative
Jeff Bonwick <Jeff.Bonwick@Sun.COM>
parents: 8214
diff changeset
   617
{
5a60f16123ba 6328632 zpool offline is a bit too conservative
Jeff Bonwick <Jeff.Bonwick@Sun.COM>
parents: 8214
diff changeset
   618
	space_seg_t *ss;
5a60f16123ba 6328632 zpool offline is a bit too conservative
Jeff Bonwick <Jeff.Bonwick@Sun.COM>
parents: 8214
diff changeset
   619
5a60f16123ba 6328632 zpool offline is a bit too conservative
Jeff Bonwick <Jeff.Bonwick@Sun.COM>
parents: 8214
diff changeset
   620
	ASSERT(MUTEX_HELD(sm->sm_lock));
5a60f16123ba 6328632 zpool offline is a bit too conservative
Jeff Bonwick <Jeff.Bonwick@Sun.COM>
parents: 8214
diff changeset
   621
5a60f16123ba 6328632 zpool offline is a bit too conservative
Jeff Bonwick <Jeff.Bonwick@Sun.COM>
parents: 8214
diff changeset
   622
	for (ss = avl_first(&sm->sm_root); ss; ss = AVL_NEXT(&sm->sm_root, ss))
5a60f16123ba 6328632 zpool offline is a bit too conservative
Jeff Bonwick <Jeff.Bonwick@Sun.COM>
parents: 8214
diff changeset
   623
		space_map_ref_add_seg(t, ss->ss_start, ss->ss_end, refcnt);
5a60f16123ba 6328632 zpool offline is a bit too conservative
Jeff Bonwick <Jeff.Bonwick@Sun.COM>
parents: 8214
diff changeset
   624
}
5a60f16123ba 6328632 zpool offline is a bit too conservative
Jeff Bonwick <Jeff.Bonwick@Sun.COM>
parents: 8214
diff changeset
   625
5a60f16123ba 6328632 zpool offline is a bit too conservative
Jeff Bonwick <Jeff.Bonwick@Sun.COM>
parents: 8214
diff changeset
   626
/*
5a60f16123ba 6328632 zpool offline is a bit too conservative
Jeff Bonwick <Jeff.Bonwick@Sun.COM>
parents: 8214
diff changeset
   627
 * Convert a reference tree into a space map.  The space map will contain
5a60f16123ba 6328632 zpool offline is a bit too conservative
Jeff Bonwick <Jeff.Bonwick@Sun.COM>
parents: 8214
diff changeset
   628
 * all members of the reference tree for which refcnt >= minref.
5a60f16123ba 6328632 zpool offline is a bit too conservative
Jeff Bonwick <Jeff.Bonwick@Sun.COM>
parents: 8214
diff changeset
   629
 */
5a60f16123ba 6328632 zpool offline is a bit too conservative
Jeff Bonwick <Jeff.Bonwick@Sun.COM>
parents: 8214
diff changeset
   630
void
5a60f16123ba 6328632 zpool offline is a bit too conservative
Jeff Bonwick <Jeff.Bonwick@Sun.COM>
parents: 8214
diff changeset
   631
space_map_ref_generate_map(avl_tree_t *t, space_map_t *sm, int64_t minref)
5a60f16123ba 6328632 zpool offline is a bit too conservative
Jeff Bonwick <Jeff.Bonwick@Sun.COM>
parents: 8214
diff changeset
   632
{
5a60f16123ba 6328632 zpool offline is a bit too conservative
Jeff Bonwick <Jeff.Bonwick@Sun.COM>
parents: 8214
diff changeset
   633
	uint64_t start = -1ULL;
5a60f16123ba 6328632 zpool offline is a bit too conservative
Jeff Bonwick <Jeff.Bonwick@Sun.COM>
parents: 8214
diff changeset
   634
	int64_t refcnt = 0;
5a60f16123ba 6328632 zpool offline is a bit too conservative
Jeff Bonwick <Jeff.Bonwick@Sun.COM>
parents: 8214
diff changeset
   635
	space_ref_t *sr;
5a60f16123ba 6328632 zpool offline is a bit too conservative
Jeff Bonwick <Jeff.Bonwick@Sun.COM>
parents: 8214
diff changeset
   636
5a60f16123ba 6328632 zpool offline is a bit too conservative
Jeff Bonwick <Jeff.Bonwick@Sun.COM>
parents: 8214
diff changeset
   637
	ASSERT(MUTEX_HELD(sm->sm_lock));
5a60f16123ba 6328632 zpool offline is a bit too conservative
Jeff Bonwick <Jeff.Bonwick@Sun.COM>
parents: 8214
diff changeset
   638
5a60f16123ba 6328632 zpool offline is a bit too conservative
Jeff Bonwick <Jeff.Bonwick@Sun.COM>
parents: 8214
diff changeset
   639
	space_map_vacate(sm, NULL, NULL);
5a60f16123ba 6328632 zpool offline is a bit too conservative
Jeff Bonwick <Jeff.Bonwick@Sun.COM>
parents: 8214
diff changeset
   640
5a60f16123ba 6328632 zpool offline is a bit too conservative
Jeff Bonwick <Jeff.Bonwick@Sun.COM>
parents: 8214
diff changeset
   641
	for (sr = avl_first(t); sr != NULL; sr = AVL_NEXT(t, sr)) {
5a60f16123ba 6328632 zpool offline is a bit too conservative
Jeff Bonwick <Jeff.Bonwick@Sun.COM>
parents: 8214
diff changeset
   642
		refcnt += sr->sr_refcnt;
5a60f16123ba 6328632 zpool offline is a bit too conservative
Jeff Bonwick <Jeff.Bonwick@Sun.COM>
parents: 8214
diff changeset
   643
		if (refcnt >= minref) {
5a60f16123ba 6328632 zpool offline is a bit too conservative
Jeff Bonwick <Jeff.Bonwick@Sun.COM>
parents: 8214
diff changeset
   644
			if (start == -1ULL) {
5a60f16123ba 6328632 zpool offline is a bit too conservative
Jeff Bonwick <Jeff.Bonwick@Sun.COM>
parents: 8214
diff changeset
   645
				start = sr->sr_offset;
5a60f16123ba 6328632 zpool offline is a bit too conservative
Jeff Bonwick <Jeff.Bonwick@Sun.COM>
parents: 8214
diff changeset
   646
			}
5a60f16123ba 6328632 zpool offline is a bit too conservative
Jeff Bonwick <Jeff.Bonwick@Sun.COM>
parents: 8214
diff changeset
   647
		} else {
5a60f16123ba 6328632 zpool offline is a bit too conservative
Jeff Bonwick <Jeff.Bonwick@Sun.COM>
parents: 8214
diff changeset
   648
			if (start != -1ULL) {
5a60f16123ba 6328632 zpool offline is a bit too conservative
Jeff Bonwick <Jeff.Bonwick@Sun.COM>
parents: 8214
diff changeset
   649
				uint64_t end = sr->sr_offset;
5a60f16123ba 6328632 zpool offline is a bit too conservative
Jeff Bonwick <Jeff.Bonwick@Sun.COM>
parents: 8214
diff changeset
   650
				ASSERT(start <= end);
5a60f16123ba 6328632 zpool offline is a bit too conservative
Jeff Bonwick <Jeff.Bonwick@Sun.COM>
parents: 8214
diff changeset
   651
				if (end > start)
5a60f16123ba 6328632 zpool offline is a bit too conservative
Jeff Bonwick <Jeff.Bonwick@Sun.COM>
parents: 8214
diff changeset
   652
					space_map_add(sm, start, end - start);
5a60f16123ba 6328632 zpool offline is a bit too conservative
Jeff Bonwick <Jeff.Bonwick@Sun.COM>
parents: 8214
diff changeset
   653
				start = -1ULL;
5a60f16123ba 6328632 zpool offline is a bit too conservative
Jeff Bonwick <Jeff.Bonwick@Sun.COM>
parents: 8214
diff changeset
   654
			}
5a60f16123ba 6328632 zpool offline is a bit too conservative
Jeff Bonwick <Jeff.Bonwick@Sun.COM>
parents: 8214
diff changeset
   655
		}
5a60f16123ba 6328632 zpool offline is a bit too conservative
Jeff Bonwick <Jeff.Bonwick@Sun.COM>
parents: 8214
diff changeset
   656
	}
5a60f16123ba 6328632 zpool offline is a bit too conservative
Jeff Bonwick <Jeff.Bonwick@Sun.COM>
parents: 8214
diff changeset
   657
	ASSERT(refcnt == 0);
5a60f16123ba 6328632 zpool offline is a bit too conservative
Jeff Bonwick <Jeff.Bonwick@Sun.COM>
parents: 8214
diff changeset
   658
	ASSERT(start == -1ULL);
5a60f16123ba 6328632 zpool offline is a bit too conservative
Jeff Bonwick <Jeff.Bonwick@Sun.COM>
parents: 8214
diff changeset
   659
}