usr/src/uts/common/fs/zfs/refcount.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
4787
602d3f97842c 6393351 unique_* could be improved
ahrens
parents: 789
diff changeset
     5
 * Common Development and Distribution License (the "License").
602d3f97842c 6393351 unique_* could be improved
ahrens
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
/*
12296
7cf402a7f374 6675946 'zpool status' should show the progress of resilvering for individual disk.
Lin Ling <Lin.Ling@Sun.COM>
parents: 4787
diff changeset
    22
 * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
13973
4972ab336f54 3464 zfs synctask code needs restructuring
Matthew Ahrens <mahrens@delphix.com>
parents: 13952
diff changeset
    23
 * Copyright (c) 2012 by Delphix. All rights reserved.
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    24
 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    25
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    26
#include <sys/zfs_context.h>
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    27
#include <sys/refcount.h>
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    28
12684
397e44ebb8a9 6710343 dnode cache should register a dnode_move() callback to limit fragmentation
Tom Erickson <Tom.Erickson@Sun.COM>
parents: 12296
diff changeset
    29
#ifdef	ZFS_DEBUG
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    30
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    31
#ifdef _KERNEL
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    32
int reference_tracking_enable = FALSE; /* runs out of memory too easily */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    33
#else
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    34
int reference_tracking_enable = TRUE;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    35
#endif
13973
4972ab336f54 3464 zfs synctask code needs restructuring
Matthew Ahrens <mahrens@delphix.com>
parents: 13952
diff changeset
    36
int reference_history = 3; /* tunable */
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    37
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    38
static kmem_cache_t *reference_cache;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    39
static kmem_cache_t *reference_history_cache;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    40
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    41
void
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    42
refcount_init(void)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    43
{
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    44
	reference_cache = kmem_cache_create("reference_cache",
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    45
	    sizeof (reference_t), 0, NULL, NULL, NULL, NULL, NULL, 0);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    46
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    47
	reference_history_cache = kmem_cache_create("reference_history_cache",
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    48
	    sizeof (uint64_t), 0, NULL, NULL, NULL, NULL, NULL, 0);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    49
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    50
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    51
void
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    52
refcount_fini(void)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    53
{
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    54
	kmem_cache_destroy(reference_cache);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    55
	kmem_cache_destroy(reference_history_cache);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    56
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    57
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    58
void
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    59
refcount_create(refcount_t *rc)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    60
{
4787
602d3f97842c 6393351 unique_* could be improved
ahrens
parents: 789
diff changeset
    61
	mutex_init(&rc->rc_mtx, NULL, MUTEX_DEFAULT, NULL);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    62
	list_create(&rc->rc_list, sizeof (reference_t),
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    63
	    offsetof(reference_t, ref_link));
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    64
	list_create(&rc->rc_removed, sizeof (reference_t),
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    65
	    offsetof(reference_t, ref_link));
4787
602d3f97842c 6393351 unique_* could be improved
ahrens
parents: 789
diff changeset
    66
	rc->rc_count = 0;
602d3f97842c 6393351 unique_* could be improved
ahrens
parents: 789
diff changeset
    67
	rc->rc_removed_count = 0;
13973
4972ab336f54 3464 zfs synctask code needs restructuring
Matthew Ahrens <mahrens@delphix.com>
parents: 13952
diff changeset
    68
	rc->rc_tracked = reference_tracking_enable;
4972ab336f54 3464 zfs synctask code needs restructuring
Matthew Ahrens <mahrens@delphix.com>
parents: 13952
diff changeset
    69
}
4972ab336f54 3464 zfs synctask code needs restructuring
Matthew Ahrens <mahrens@delphix.com>
parents: 13952
diff changeset
    70
4972ab336f54 3464 zfs synctask code needs restructuring
Matthew Ahrens <mahrens@delphix.com>
parents: 13952
diff changeset
    71
void
4972ab336f54 3464 zfs synctask code needs restructuring
Matthew Ahrens <mahrens@delphix.com>
parents: 13952
diff changeset
    72
refcount_create_untracked(refcount_t *rc)
4972ab336f54 3464 zfs synctask code needs restructuring
Matthew Ahrens <mahrens@delphix.com>
parents: 13952
diff changeset
    73
{
4972ab336f54 3464 zfs synctask code needs restructuring
Matthew Ahrens <mahrens@delphix.com>
parents: 13952
diff changeset
    74
	refcount_create(rc);
4972ab336f54 3464 zfs synctask code needs restructuring
Matthew Ahrens <mahrens@delphix.com>
parents: 13952
diff changeset
    75
	rc->rc_tracked = B_FALSE;
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    76
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    77
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    78
void
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    79
refcount_destroy_many(refcount_t *rc, uint64_t number)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    80
{
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    81
	reference_t *ref;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    82
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    83
	ASSERT(rc->rc_count == number);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    84
	while (ref = list_head(&rc->rc_list)) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    85
		list_remove(&rc->rc_list, ref);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    86
		kmem_cache_free(reference_cache, ref);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    87
	}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    88
	list_destroy(&rc->rc_list);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    89
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    90
	while (ref = list_head(&rc->rc_removed)) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    91
		list_remove(&rc->rc_removed, ref);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    92
		kmem_cache_free(reference_history_cache, ref->ref_removed);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    93
		kmem_cache_free(reference_cache, ref);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    94
	}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    95
	list_destroy(&rc->rc_removed);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    96
	mutex_destroy(&rc->rc_mtx);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    97
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    98
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    99
void
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   100
refcount_destroy(refcount_t *rc)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   101
{
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   102
	refcount_destroy_many(rc, 0);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   103
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   104
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   105
int
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   106
refcount_is_zero(refcount_t *rc)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   107
{
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   108
	return (rc->rc_count == 0);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   109
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   110
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   111
int64_t
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   112
refcount_count(refcount_t *rc)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   113
{
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   114
	return (rc->rc_count);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   115
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   116
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   117
int64_t
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   118
refcount_add_many(refcount_t *rc, uint64_t number, void *holder)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   119
{
13952
7a22d0770fc8 3522 zfs module should not allow uninitialized variables
George Wilson <george.wilson@delphix.com>
parents: 12684
diff changeset
   120
	reference_t *ref = NULL;
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   121
	int64_t count;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   122
13973
4972ab336f54 3464 zfs synctask code needs restructuring
Matthew Ahrens <mahrens@delphix.com>
parents: 13952
diff changeset
   123
	if (rc->rc_tracked) {
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   124
		ref = kmem_cache_alloc(reference_cache, KM_SLEEP);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   125
		ref->ref_holder = holder;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   126
		ref->ref_number = number;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   127
	}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   128
	mutex_enter(&rc->rc_mtx);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   129
	ASSERT(rc->rc_count >= 0);
13973
4972ab336f54 3464 zfs synctask code needs restructuring
Matthew Ahrens <mahrens@delphix.com>
parents: 13952
diff changeset
   130
	if (rc->rc_tracked)
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   131
		list_insert_head(&rc->rc_list, ref);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   132
	rc->rc_count += number;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   133
	count = rc->rc_count;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   134
	mutex_exit(&rc->rc_mtx);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   135
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   136
	return (count);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   137
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   138
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   139
int64_t
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   140
refcount_add(refcount_t *rc, void *holder)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   141
{
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   142
	return (refcount_add_many(rc, 1, holder));
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   143
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   144
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   145
int64_t
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   146
refcount_remove_many(refcount_t *rc, uint64_t number, void *holder)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   147
{
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   148
	reference_t *ref;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   149
	int64_t count;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   150
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   151
	mutex_enter(&rc->rc_mtx);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   152
	ASSERT(rc->rc_count >= number);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   153
13973
4972ab336f54 3464 zfs synctask code needs restructuring
Matthew Ahrens <mahrens@delphix.com>
parents: 13952
diff changeset
   154
	if (!rc->rc_tracked) {
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   155
		rc->rc_count -= number;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   156
		count = rc->rc_count;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   157
		mutex_exit(&rc->rc_mtx);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   158
		return (count);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   159
	}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   160
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   161
	for (ref = list_head(&rc->rc_list); ref;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   162
	    ref = list_next(&rc->rc_list, ref)) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   163
		if (ref->ref_holder == holder && ref->ref_number == number) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   164
			list_remove(&rc->rc_list, ref);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   165
			if (reference_history > 0) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   166
				ref->ref_removed =
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   167
				    kmem_cache_alloc(reference_history_cache,
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   168
				    KM_SLEEP);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   169
				list_insert_head(&rc->rc_removed, ref);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   170
				rc->rc_removed_count++;
13973
4972ab336f54 3464 zfs synctask code needs restructuring
Matthew Ahrens <mahrens@delphix.com>
parents: 13952
diff changeset
   171
				if (rc->rc_removed_count > reference_history) {
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   172
					ref = list_tail(&rc->rc_removed);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   173
					list_remove(&rc->rc_removed, ref);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   174
					kmem_cache_free(reference_history_cache,
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   175
					    ref->ref_removed);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   176
					kmem_cache_free(reference_cache, ref);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   177
					rc->rc_removed_count--;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   178
				}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   179
			} else {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   180
				kmem_cache_free(reference_cache, ref);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   181
			}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   182
			rc->rc_count -= number;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   183
			count = rc->rc_count;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   184
			mutex_exit(&rc->rc_mtx);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   185
			return (count);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   186
		}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   187
	}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   188
	panic("No such hold %p on refcount %llx", holder,
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   189
	    (u_longlong_t)(uintptr_t)rc);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   190
	return (-1);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   191
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   192
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   193
int64_t
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   194
refcount_remove(refcount_t *rc, void *holder)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   195
{
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   196
	return (refcount_remove_many(rc, 1, holder));
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   197
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   198
12684
397e44ebb8a9 6710343 dnode cache should register a dnode_move() callback to limit fragmentation
Tom Erickson <Tom.Erickson@Sun.COM>
parents: 12296
diff changeset
   199
void
397e44ebb8a9 6710343 dnode cache should register a dnode_move() callback to limit fragmentation
Tom Erickson <Tom.Erickson@Sun.COM>
parents: 12296
diff changeset
   200
refcount_transfer(refcount_t *dst, refcount_t *src)
397e44ebb8a9 6710343 dnode cache should register a dnode_move() callback to limit fragmentation
Tom Erickson <Tom.Erickson@Sun.COM>
parents: 12296
diff changeset
   201
{
397e44ebb8a9 6710343 dnode cache should register a dnode_move() callback to limit fragmentation
Tom Erickson <Tom.Erickson@Sun.COM>
parents: 12296
diff changeset
   202
	int64_t count, removed_count;
397e44ebb8a9 6710343 dnode cache should register a dnode_move() callback to limit fragmentation
Tom Erickson <Tom.Erickson@Sun.COM>
parents: 12296
diff changeset
   203
	list_t list, removed;
397e44ebb8a9 6710343 dnode cache should register a dnode_move() callback to limit fragmentation
Tom Erickson <Tom.Erickson@Sun.COM>
parents: 12296
diff changeset
   204
397e44ebb8a9 6710343 dnode cache should register a dnode_move() callback to limit fragmentation
Tom Erickson <Tom.Erickson@Sun.COM>
parents: 12296
diff changeset
   205
	list_create(&list, sizeof (reference_t),
397e44ebb8a9 6710343 dnode cache should register a dnode_move() callback to limit fragmentation
Tom Erickson <Tom.Erickson@Sun.COM>
parents: 12296
diff changeset
   206
	    offsetof(reference_t, ref_link));
397e44ebb8a9 6710343 dnode cache should register a dnode_move() callback to limit fragmentation
Tom Erickson <Tom.Erickson@Sun.COM>
parents: 12296
diff changeset
   207
	list_create(&removed, sizeof (reference_t),
397e44ebb8a9 6710343 dnode cache should register a dnode_move() callback to limit fragmentation
Tom Erickson <Tom.Erickson@Sun.COM>
parents: 12296
diff changeset
   208
	    offsetof(reference_t, ref_link));
397e44ebb8a9 6710343 dnode cache should register a dnode_move() callback to limit fragmentation
Tom Erickson <Tom.Erickson@Sun.COM>
parents: 12296
diff changeset
   209
397e44ebb8a9 6710343 dnode cache should register a dnode_move() callback to limit fragmentation
Tom Erickson <Tom.Erickson@Sun.COM>
parents: 12296
diff changeset
   210
	mutex_enter(&src->rc_mtx);
397e44ebb8a9 6710343 dnode cache should register a dnode_move() callback to limit fragmentation
Tom Erickson <Tom.Erickson@Sun.COM>
parents: 12296
diff changeset
   211
	count = src->rc_count;
397e44ebb8a9 6710343 dnode cache should register a dnode_move() callback to limit fragmentation
Tom Erickson <Tom.Erickson@Sun.COM>
parents: 12296
diff changeset
   212
	removed_count = src->rc_removed_count;
397e44ebb8a9 6710343 dnode cache should register a dnode_move() callback to limit fragmentation
Tom Erickson <Tom.Erickson@Sun.COM>
parents: 12296
diff changeset
   213
	src->rc_count = 0;
397e44ebb8a9 6710343 dnode cache should register a dnode_move() callback to limit fragmentation
Tom Erickson <Tom.Erickson@Sun.COM>
parents: 12296
diff changeset
   214
	src->rc_removed_count = 0;
397e44ebb8a9 6710343 dnode cache should register a dnode_move() callback to limit fragmentation
Tom Erickson <Tom.Erickson@Sun.COM>
parents: 12296
diff changeset
   215
	list_move_tail(&list, &src->rc_list);
397e44ebb8a9 6710343 dnode cache should register a dnode_move() callback to limit fragmentation
Tom Erickson <Tom.Erickson@Sun.COM>
parents: 12296
diff changeset
   216
	list_move_tail(&removed, &src->rc_removed);
397e44ebb8a9 6710343 dnode cache should register a dnode_move() callback to limit fragmentation
Tom Erickson <Tom.Erickson@Sun.COM>
parents: 12296
diff changeset
   217
	mutex_exit(&src->rc_mtx);
397e44ebb8a9 6710343 dnode cache should register a dnode_move() callback to limit fragmentation
Tom Erickson <Tom.Erickson@Sun.COM>
parents: 12296
diff changeset
   218
397e44ebb8a9 6710343 dnode cache should register a dnode_move() callback to limit fragmentation
Tom Erickson <Tom.Erickson@Sun.COM>
parents: 12296
diff changeset
   219
	mutex_enter(&dst->rc_mtx);
397e44ebb8a9 6710343 dnode cache should register a dnode_move() callback to limit fragmentation
Tom Erickson <Tom.Erickson@Sun.COM>
parents: 12296
diff changeset
   220
	dst->rc_count += count;
397e44ebb8a9 6710343 dnode cache should register a dnode_move() callback to limit fragmentation
Tom Erickson <Tom.Erickson@Sun.COM>
parents: 12296
diff changeset
   221
	dst->rc_removed_count += removed_count;
397e44ebb8a9 6710343 dnode cache should register a dnode_move() callback to limit fragmentation
Tom Erickson <Tom.Erickson@Sun.COM>
parents: 12296
diff changeset
   222
	list_move_tail(&dst->rc_list, &list);
397e44ebb8a9 6710343 dnode cache should register a dnode_move() callback to limit fragmentation
Tom Erickson <Tom.Erickson@Sun.COM>
parents: 12296
diff changeset
   223
	list_move_tail(&dst->rc_removed, &removed);
397e44ebb8a9 6710343 dnode cache should register a dnode_move() callback to limit fragmentation
Tom Erickson <Tom.Erickson@Sun.COM>
parents: 12296
diff changeset
   224
	mutex_exit(&dst->rc_mtx);
397e44ebb8a9 6710343 dnode cache should register a dnode_move() callback to limit fragmentation
Tom Erickson <Tom.Erickson@Sun.COM>
parents: 12296
diff changeset
   225
397e44ebb8a9 6710343 dnode cache should register a dnode_move() callback to limit fragmentation
Tom Erickson <Tom.Erickson@Sun.COM>
parents: 12296
diff changeset
   226
	list_destroy(&list);
397e44ebb8a9 6710343 dnode cache should register a dnode_move() callback to limit fragmentation
Tom Erickson <Tom.Erickson@Sun.COM>
parents: 12296
diff changeset
   227
	list_destroy(&removed);
397e44ebb8a9 6710343 dnode cache should register a dnode_move() callback to limit fragmentation
Tom Erickson <Tom.Erickson@Sun.COM>
parents: 12296
diff changeset
   228
}
397e44ebb8a9 6710343 dnode cache should register a dnode_move() callback to limit fragmentation
Tom Erickson <Tom.Erickson@Sun.COM>
parents: 12296
diff changeset
   229
397e44ebb8a9 6710343 dnode cache should register a dnode_move() callback to limit fragmentation
Tom Erickson <Tom.Erickson@Sun.COM>
parents: 12296
diff changeset
   230
#endif	/* ZFS_DEBUG */