summaryrefslogtreecommitdiffstats
path: root/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sa.c
diff options
context:
space:
mode:
authormav <mav@FreeBSD.org>2015-10-03 07:29:56 +0000
committermav <mav@FreeBSD.org>2015-10-03 07:29:56 +0000
commit4a52577541ebbe34a9fa8abe3948a8514c63258c (patch)
tree8ed8ab1f80ef30fc8881b08dd4e4e6ea57f4f7c3 /sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sa.c
parent3529a708dddb3cca632de7b55ab67db8aa2f543d (diff)
downloadFreeBSD-src-4a52577541ebbe34a9fa8abe3948a8514c63258c.zip
FreeBSD-src-4a52577541ebbe34a9fa8abe3948a8514c63258c.tar.gz
MFC r286575: 5056 ZFS deadlock on db_mtx and dn_holds
Reviewed by: Will Andrews <willa@spectralogic.com> Reviewed by: Matt Ahrens <mahrens@delphix.com> Reviewed by: George Wilson <george.wilson@delphix.com> Approved by: Dan McDonald <danmcd@omniti.com> Author: Justin Gibbs <justing@spectralogic.com> illumos/illumos-gate@bc9014e6a81272073b9854d9f65dd59e18d18c35
Diffstat (limited to 'sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sa.c')
-rw-r--r--sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sa.c41
1 files changed, 21 insertions, 20 deletions
diff --git a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sa.c b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sa.c
index 0302647..dfdb38c 100644
--- a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sa.c
+++ b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sa.c
@@ -23,6 +23,7 @@
* Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
* Portions Copyright 2011 iXsystems, Inc
* Copyright (c) 2013 by Delphix. All rights reserved.
+ * Copyright (c) 2014 Spectra Logic Corporation, All rights reserved.
*/
#include <sys/zfs_context.h>
@@ -219,6 +220,7 @@ static void
sa_cache_destructor(void *buf, void *unused)
{
sa_handle_t *hdl = buf;
+ hdl->sa_dbu.dbu_evict_func = NULL;
mutex_destroy(&hdl->sa_lock);
}
@@ -1298,10 +1300,10 @@ sa_build_index(sa_handle_t *hdl, sa_buf_type_t buftype)
}
/*ARGSUSED*/
-void
-sa_evict(dmu_buf_t *db, void *sap)
+static void
+sa_evict(void *dbu)
{
- panic("evicting sa dbuf %p\n", (void *)db);
+ panic("evicting sa dbuf\n");
}
static void
@@ -1340,9 +1342,10 @@ sa_idx_tab_hold(objset_t *os, sa_idx_tab_t *idx_tab)
void
sa_handle_destroy(sa_handle_t *hdl)
{
+ dmu_buf_t *db = hdl->sa_bonus;
+
mutex_enter(&hdl->sa_lock);
- (void) dmu_buf_update_user((dmu_buf_t *)hdl->sa_bonus, hdl,
- NULL, NULL);
+ (void) dmu_buf_remove_user(db, &hdl->sa_dbu);
if (hdl->sa_bonus_tab)
sa_idx_tab_rele(hdl->sa_os, hdl->sa_bonus_tab);
@@ -1365,7 +1368,7 @@ sa_handle_get_from_db(objset_t *os, dmu_buf_t *db, void *userp,
{
int error = 0;
dmu_object_info_t doi;
- sa_handle_t *handle;
+ sa_handle_t *handle = NULL;
#ifdef ZFS_DEBUG
dmu_object_info_from_db(db, &doi);
@@ -1375,9 +1378,12 @@ sa_handle_get_from_db(objset_t *os, dmu_buf_t *db, void *userp,
/* find handle, if it exists */
/* if one doesn't exist then create a new one, and initialize it */
- handle = (hdl_type == SA_HDL_SHARED) ? dmu_buf_get_user(db) : NULL;
+ if (hdl_type == SA_HDL_SHARED)
+ handle = dmu_buf_get_user(db);
+
if (handle == NULL) {
- sa_handle_t *newhandle;
+ sa_handle_t *winner = NULL;
+
handle = kmem_cache_alloc(sa_cache, KM_SLEEP);
handle->sa_userp = userp;
handle->sa_bonus = db;
@@ -1387,12 +1393,15 @@ sa_handle_get_from_db(objset_t *os, dmu_buf_t *db, void *userp,
handle->sa_spill_tab = NULL;
error = sa_build_index(handle, SA_BONUS);
- newhandle = (hdl_type == SA_HDL_SHARED) ?
- dmu_buf_set_user_ie(db, handle, sa_evict) : NULL;
- if (newhandle != NULL) {
+ if (hdl_type == SA_HDL_SHARED) {
+ dmu_buf_init_user(&handle->sa_dbu, sa_evict, NULL);
+ winner = dmu_buf_set_user_ie(db, &handle->sa_dbu);
+ }
+
+ if (winner != NULL) {
kmem_cache_free(sa_cache, handle);
- handle = newhandle;
+ handle = winner;
}
}
*handlepp = handle;
@@ -1910,14 +1919,6 @@ sa_object_size(sa_handle_t *hdl, uint32_t *blksize, u_longlong_t *nblocks)
}
void
-sa_update_user(sa_handle_t *newhdl, sa_handle_t *oldhdl)
-{
- (void) dmu_buf_update_user((dmu_buf_t *)newhdl->sa_bonus,
- oldhdl, newhdl, sa_evict);
- oldhdl->sa_bonus = NULL;
-}
-
-void
sa_set_userp(sa_handle_t *hdl, void *ptr)
{
hdl->sa_userp = ptr;
OpenPOWER on IntegriCloud