summaryrefslogtreecommitdiffstats
path: root/module/zfs
diff options
context:
space:
mode:
Diffstat (limited to 'module/zfs')
-rw-r--r--module/zfs/dmu.c52
-rw-r--r--module/zfs/dmu_recv.c229
-rw-r--r--module/zfs/zfs_ioctl.c36
-rw-r--r--module/zfs/zfs_onexit.c79
4 files changed, 19 insertions, 377 deletions
diff --git a/module/zfs/dmu.c b/module/zfs/dmu.c
index 6eb935720..a21ac8d74 100644
--- a/module/zfs/dmu.c
+++ b/module/zfs/dmu.c
@@ -20,7 +20,7 @@
*/
/*
* Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
- * Copyright (c) 2011, 2018 by Delphix. All rights reserved.
+ * Copyright (c) 2011, 2020 by Delphix. All rights reserved.
* Copyright (c) 2013 by Saso Kiselkov. All rights reserved.
* Copyright (c) 2013, Joyent, Inc. All rights reserved.
* Copyright (c) 2016, Nexenta Systems, Inc. All rights reserved.
@@ -1560,56 +1560,6 @@ dmu_return_arcbuf(arc_buf_t *buf)
arc_buf_destroy(buf, FTAG);
}
-void
-dmu_copy_from_buf(objset_t *os, uint64_t object, uint64_t offset,
- dmu_buf_t *handle, dmu_tx_t *tx)
-{
- dmu_buf_t *dst_handle;
- dmu_buf_impl_t *dstdb;
- dmu_buf_impl_t *srcdb = (dmu_buf_impl_t *)handle;
- dmu_object_type_t type;
- arc_buf_t *abuf;
- uint64_t datalen;
- boolean_t byteorder;
- uint8_t salt[ZIO_DATA_SALT_LEN];
- uint8_t iv[ZIO_DATA_IV_LEN];
- uint8_t mac[ZIO_DATA_MAC_LEN];
-
- ASSERT3P(srcdb->db_buf, !=, NULL);
-
- /* hold the db that we want to write to */
- VERIFY0(dmu_buf_hold(os, object, offset, FTAG, &dst_handle,
- DMU_READ_NO_DECRYPT));
- dstdb = (dmu_buf_impl_t *)dst_handle;
- datalen = arc_buf_size(srcdb->db_buf);
-
- DB_DNODE_ENTER(dstdb);
- type = DB_DNODE(dstdb)->dn_type;
- DB_DNODE_EXIT(dstdb);
-
- /* allocated an arc buffer that matches the type of srcdb->db_buf */
- if (arc_is_encrypted(srcdb->db_buf)) {
- arc_get_raw_params(srcdb->db_buf, &byteorder, salt, iv, mac);
- abuf = arc_loan_raw_buf(os->os_spa, dmu_objset_id(os),
- byteorder, salt, iv, mac, type,
- datalen, arc_buf_lsize(srcdb->db_buf),
- arc_get_compression(srcdb->db_buf));
- } else {
- /* we won't get a compressed db back from dmu_buf_hold() */
- ASSERT3U(arc_get_compression(srcdb->db_buf),
- ==, ZIO_COMPRESS_OFF);
- abuf = arc_loan_buf(os->os_spa,
- DMU_OT_IS_METADATA(type), datalen);
- }
-
- ASSERT3U(datalen, ==, arc_buf_size(abuf));
-
- /* copy the data to the new buffer and assign it to the dstdb */
- bcopy(srcdb->db_buf->b_data, abuf->b_data, datalen);
- dbuf_assign_arcbuf(dstdb, abuf, tx);
- dmu_buf_rele(dst_handle, FTAG);
-}
-
/*
* When possible directly assign passed loaned arc buffer to a dbuf.
* If this is not possible copy the contents of passed arc buf via
diff --git a/module/zfs/dmu_recv.c b/module/zfs/dmu_recv.c
index 9c82cecc6..817c85b93 100644
--- a/module/zfs/dmu_recv.c
+++ b/module/zfs/dmu_recv.c
@@ -21,7 +21,7 @@
/*
* Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
* Copyright 2011 Nexenta Systems, Inc. All rights reserved.
- * Copyright (c) 2011, 2018 by Delphix. All rights reserved.
+ * Copyright (c) 2011, 2020 by Delphix. All rights reserved.
* Copyright (c) 2014, Joyent, Inc. All rights reserved.
* Copyright 2014 HybridCluster. All rights reserved.
* Copyright (c) 2018, loli10K <[email protected]>. All rights reserved.
@@ -101,8 +101,6 @@ struct receive_writer_arg {
boolean_t done;
int err;
- /* A map from guid to dataset to help handle dedup'd streams. */
- avl_tree_t *guid_to_ds_map;
boolean_t resumable;
boolean_t raw; /* DMU_BACKUP_FEATURE_RAW set */
boolean_t spill; /* DRR_FLAG_SPILL_BLOCK set */
@@ -123,13 +121,6 @@ struct receive_writer_arg {
boolean_t or_byteorder;
};
-typedef struct guid_map_entry {
- uint64_t guid;
- boolean_t raw;
- objset_t *gme_os;
- avl_node_t avlnode;
-} guid_map_entry_t;
-
typedef struct dmu_recv_begin_arg {
const char *drba_origin;
dmu_recv_cookie_t *drba_cookie;
@@ -1213,38 +1204,6 @@ dmu_recv_begin(char *tofs, char *tosnap, dmu_replay_record_t *drr_begin,
}
static int
-guid_compare(const void *arg1, const void *arg2)
-{
- const guid_map_entry_t *gmep1 = (const guid_map_entry_t *)arg1;
- const guid_map_entry_t *gmep2 = (const guid_map_entry_t *)arg2;
-
- return (TREE_CMP(gmep1->guid, gmep2->guid));
-}
-
-static void
-free_guid_map_onexit(void *arg)
-{
- avl_tree_t *ca = arg;
- void *cookie = NULL;
- guid_map_entry_t *gmep;
-
- while ((gmep = avl_destroy_nodes(ca, &cookie)) != NULL) {
- ds_hold_flags_t dsflags = DS_HOLD_FLAG_DECRYPT;
-
- if (gmep->raw) {
- gmep->gme_os->os_raw_receive = B_FALSE;
- dsflags &= ~DS_HOLD_FLAG_DECRYPT;
- }
-
- dsl_dataset_disown(gmep->gme_os->os_dsl_dataset,
- dsflags, gmep);
- kmem_free(gmep, sizeof (guid_map_entry_t));
- }
- avl_destroy(ca);
- kmem_free(ca, sizeof (avl_tree_t));
-}
-
-static int
receive_read(dmu_recv_cookie_t *drc, int len, void *buf)
{
int done = 0;
@@ -1845,81 +1804,6 @@ receive_process_write_record(struct receive_writer_arg *rwa,
return (EAGAIN);
}
-/*
- * Handle a DRR_WRITE_BYREF record. This record is used in dedup'ed
- * streams to refer to a copy of the data that is already on the
- * system because it came in earlier in the stream. This function
- * finds the earlier copy of the data, and uses that copy instead of
- * data from the stream to fulfill this write.
- */
-noinline static int
-receive_write_byref(struct receive_writer_arg *rwa,
- struct drr_write_byref *drrwbr)
-{
- dmu_tx_t *tx;
- int err;
- guid_map_entry_t gmesrch;
- guid_map_entry_t *gmep;
- avl_index_t where;
- objset_t *ref_os = NULL;
- int flags = DMU_READ_PREFETCH;
- dmu_buf_t *dbp;
-
- if (drrwbr->drr_offset + drrwbr->drr_length < drrwbr->drr_offset)
- return (SET_ERROR(EINVAL));
-
- /*
- * If the GUID of the referenced dataset is different from the
- * GUID of the target dataset, find the referenced dataset.
- */
- if (drrwbr->drr_toguid != drrwbr->drr_refguid) {
- gmesrch.guid = drrwbr->drr_refguid;
- if ((gmep = avl_find(rwa->guid_to_ds_map, &gmesrch,
- &where)) == NULL) {
- return (SET_ERROR(EINVAL));
- }
- ref_os = gmep->gme_os;
- } else {
- ref_os = rwa->os;
- }
-
- if (drrwbr->drr_object > rwa->max_object)
- rwa->max_object = drrwbr->drr_object;
-
- if (rwa->raw)
- flags |= DMU_READ_NO_DECRYPT;
-
- /* may return either a regular db or an encrypted one */
- err = dmu_buf_hold(ref_os, drrwbr->drr_refobject,
- drrwbr->drr_refoffset, FTAG, &dbp, flags);
- if (err != 0)
- return (err);
-
- tx = dmu_tx_create(rwa->os);
-
- dmu_tx_hold_write(tx, drrwbr->drr_object,
- drrwbr->drr_offset, drrwbr->drr_length);
- err = dmu_tx_assign(tx, TXG_WAIT);
- if (err != 0) {
- dmu_tx_abort(tx);
- return (err);
- }
-
- if (rwa->raw) {
- dmu_copy_from_buf(rwa->os, drrwbr->drr_object,
- drrwbr->drr_offset, dbp, tx);
- } else {
- dmu_write(rwa->os, drrwbr->drr_object,
- drrwbr->drr_offset, drrwbr->drr_length, dbp->db_data, tx);
- }
- dmu_buf_rele(dbp, FTAG);
-
- /* See comment in restore_write. */
- save_resume_state(rwa, drrwbr->drr_object, drrwbr->drr_offset, tx);
- dmu_tx_commit(tx);
- return (0);
-}
-
static int
receive_write_embedded(struct receive_writer_arg *rwa,
struct drr_write_embedded *drrwe, void *data)
@@ -2607,13 +2491,6 @@ receive_process_record(struct receive_writer_arg *rwa,
}
break;
}
- case DRR_WRITE_BYREF:
- {
- struct drr_write_byref *drrwbr =
- &rrd->header.drr_u.drr_write_byref;
- err = receive_write_byref(rwa, drrwbr);
- break;
- }
case DRR_WRITE_EMBEDDED:
{
struct drr_write_embedded *drrwe =
@@ -2754,8 +2631,7 @@ resume_check(dmu_recv_cookie_t *drc, nvlist_t *begin_nvl)
* NB: callers *must* call dmu_recv_end() if this succeeds.
*/
int
-dmu_recv_stream(dmu_recv_cookie_t *drc, int cleanup_fd,
- uint64_t *action_handlep, offset_t *voffp)
+dmu_recv_stream(dmu_recv_cookie_t *drc, offset_t *voffp)
{
int err = 0;
struct receive_writer_arg *rwa = kmem_zalloc(sizeof (*rwa), KM_SLEEP);
@@ -2779,41 +2655,6 @@ dmu_recv_stream(dmu_recv_cookie_t *drc, int cleanup_fd,
ASSERT0(drc->drc_os->os_encrypted &&
(drc->drc_featureflags & DMU_BACKUP_FEATURE_EMBED_DATA));
- /* if this stream is dedup'ed, set up the avl tree for guid mapping */
- if (drc->drc_featureflags & DMU_BACKUP_FEATURE_DEDUP) {
- minor_t minor;
-
- if (cleanup_fd == -1) {
- err = SET_ERROR(EBADF);
- goto out;
- }
- err = zfs_onexit_fd_hold(cleanup_fd, &minor);
- if (err != 0) {
- cleanup_fd = -1;
- goto out;
- }
-
- if (*action_handlep == 0) {
- rwa->guid_to_ds_map =
- kmem_alloc(sizeof (avl_tree_t), KM_SLEEP);
- avl_create(rwa->guid_to_ds_map, guid_compare,
- sizeof (guid_map_entry_t),
- offsetof(guid_map_entry_t, avlnode));
- err = zfs_onexit_add_cb(minor,
- free_guid_map_onexit, rwa->guid_to_ds_map,
- action_handlep);
- if (err != 0)
- goto out;
- } else {
- err = zfs_onexit_cb_data(minor, *action_handlep,
- (void **)&rwa->guid_to_ds_map);
- if (err != 0)
- goto out;
- }
-
- drc->drc_guid_to_ds_map = rwa->guid_to_ds_map;
- }
-
/* handle DSL encryption key payload */
if (drc->drc_featureflags & DMU_BACKUP_FEATURE_RAW) {
nvlist_t *keynvl = NULL;
@@ -2980,9 +2821,6 @@ out:
kmem_free(rwa, sizeof (*rwa));
nvlist_free(drc->drc_begin_nvl);
- if ((drc->drc_featureflags & DMU_BACKUP_FEATURE_DEDUP) &&
- (cleanup_fd != -1))
- zfs_onexit_fd_rele(cleanup_fd);
if (err != 0) {
/*
@@ -3083,6 +2921,7 @@ dmu_recv_end_sync(void *arg, dmu_tx_t *tx)
dmu_recv_cookie_t *drc = arg;
dsl_pool_t *dp = dmu_tx_pool(tx);
boolean_t encrypted = drc->drc_ds->ds_dir->dd_crypto_obj != 0;
+ uint64_t newsnapobj;
spa_history_log_internal_ds(drc->drc_ds, "finish receiving",
tx, "snap=%s", drc->drc_tosnap);
@@ -3148,7 +2987,7 @@ dmu_recv_end_sync(void *arg, dmu_tx_t *tx)
dsl_dataset_phys(origin_head)->ds_flags &=
~DS_FLAG_INCONSISTENT;
- drc->drc_newsnapobj =
+ newsnapobj =
dsl_dataset_phys(origin_head)->ds_prev_snap_obj;
dsl_dataset_rele(origin_head, FTAG);
@@ -3188,7 +3027,7 @@ dmu_recv_end_sync(void *arg, dmu_tx_t *tx)
(void) zap_remove(dp->dp_meta_objset, ds->ds_object,
DS_FIELD_RESUME_REDACT_BOOKMARK_SNAPS, tx);
}
- drc->drc_newsnapobj =
+ newsnapobj =
dsl_dataset_phys(drc->drc_ds)->ds_prev_snap_obj;
}
@@ -3203,9 +3042,9 @@ dmu_recv_end_sync(void *arg, dmu_tx_t *tx)
* value.
*/
if (drc->drc_raw && drc->drc_ivset_guid != 0) {
- dmu_object_zapify(dp->dp_meta_objset, drc->drc_newsnapobj,
+ dmu_object_zapify(dp->dp_meta_objset, newsnapobj,
DMU_OT_DSL_DATASET, tx);
- VERIFY0(zap_update(dp->dp_meta_objset, drc->drc_newsnapobj,
+ VERIFY0(zap_update(dp->dp_meta_objset, newsnapobj,
DS_FIELD_IVSET_GUID, sizeof (uint64_t), 1,
&drc->drc_ivset_guid, tx));
}
@@ -3226,54 +3065,6 @@ dmu_recv_end_sync(void *arg, dmu_tx_t *tx)
drc->drc_ds = NULL;
}
-static int
-add_ds_to_guidmap(const char *name, avl_tree_t *guid_map, uint64_t snapobj,
- boolean_t raw)
-{
- dsl_pool_t *dp;
- dsl_dataset_t *snapds;
- guid_map_entry_t *gmep;
- objset_t *os;
- ds_hold_flags_t dsflags = (raw) ? 0 : DS_HOLD_FLAG_DECRYPT;
- int err;
-
- ASSERT(guid_map != NULL);
-
- err = dsl_pool_hold(name, FTAG, &dp);
- if (err != 0)
- return (err);
- gmep = kmem_alloc(sizeof (*gmep), KM_SLEEP);
- err = dsl_dataset_own_obj(dp, snapobj, dsflags, gmep, &snapds);
-
- if (err == 0) {
- err = dmu_objset_from_ds(snapds, &os);
- if (err != 0) {
- dsl_dataset_disown(snapds, dsflags, FTAG);
- dsl_pool_rele(dp, FTAG);
- kmem_free(gmep, sizeof (*gmep));
- return (err);
- }
- /*
- * If this is a deduplicated raw send stream, we need
- * to make sure that we can still read raw blocks from
- * earlier datasets in the stream, so we set the
- * os_raw_receive flag now.
- */
- if (raw)
- os->os_raw_receive = B_TRUE;
-
- gmep->raw = raw;
- gmep->guid = dsl_dataset_phys(snapds)->ds_guid;
- gmep->gme_os = os;
- avl_add(guid_map, gmep);
- } else {
- kmem_free(gmep, sizeof (*gmep));
- }
-
- dsl_pool_rele(dp, FTAG);
- return (err);
-}
-
static int dmu_recv_end_modified_blocks = 3;
static int
@@ -3325,12 +3116,6 @@ dmu_recv_end(dmu_recv_cookie_t *drc, void *owner)
drc->drc_tofs, drc->drc_tosnap);
zvol_create_minor(snapname);
kmem_strfree(snapname);
-
- if (drc->drc_guid_to_ds_map != NULL) {
- (void) add_ds_to_guidmap(drc->drc_tofs,
- drc->drc_guid_to_ds_map,
- drc->drc_newsnapobj, drc->drc_raw);
- }
}
return (error);
}
diff --git a/module/zfs/zfs_ioctl.c b/module/zfs/zfs_ioctl.c
index 5c53eb637..2104bef71 100644
--- a/module/zfs/zfs_ioctl.c
+++ b/module/zfs/zfs_ioctl.c
@@ -27,7 +27,7 @@
* Copyright (c) 2014, 2016 Joyent, Inc. All rights reserved.
* Copyright 2016 Nexenta Systems, Inc. All rights reserved.
* Copyright (c) 2014, Joyent, Inc. All rights reserved.
- * Copyright (c) 2011, 2018 by Delphix. All rights reserved.
+ * Copyright (c) 2011, 2020 by Delphix. All rights reserved.
* Copyright (c) 2013 by Saso Kiselkov. All rights reserved.
* Copyright (c) 2013 Steven Hartland. All rights reserved.
* Copyright (c) 2014 Integros [integros.com]
@@ -4765,9 +4765,9 @@ static boolean_t zfs_ioc_recv_inject_err;
static int
zfs_ioc_recv_impl(char *tofs, char *tosnap, char *origin, nvlist_t *recvprops,
nvlist_t *localprops, nvlist_t *hidden_args, boolean_t force,
- boolean_t resumable, int input_fd, dmu_replay_record_t *begin_record,
- int cleanup_fd, uint64_t *read_bytes, uint64_t *errflags,
- uint64_t *action_handle, nvlist_t **errors)
+ boolean_t resumable, int input_fd,
+ dmu_replay_record_t *begin_record, uint64_t *read_bytes,
+ uint64_t *errflags, nvlist_t **errors)
{
dmu_recv_cookie_t drc;
int error = 0;
@@ -4896,7 +4896,7 @@ zfs_ioc_recv_impl(char *tofs, char *tosnap, char *origin, nvlist_t *recvprops,
nvlist_free(xprops);
}
- error = dmu_recv_stream(&drc, cleanup_fd, action_handle, &off);
+ error = dmu_recv_stream(&drc, &off);
if (error == 0) {
zfsvfs_t *zfsvfs = NULL;
@@ -5088,13 +5088,10 @@ out:
* zc_cookie file descriptor to recv from
* zc_begin_record the BEGIN record of the stream (not byteswapped)
* zc_guid force flag
- * zc_cleanup_fd cleanup-on-exit file descriptor
- * zc_action_handle handle for this guid/ds mapping (or zero on first call)
*
* outputs:
* zc_cookie number of bytes read
* zc_obj zprop_errflags_t
- * zc_action_handle handle for this guid/ds mapping
* zc_nvlist_dst{_size} error for each unapplied received property
*/
static int
@@ -5137,8 +5134,7 @@ zfs_ioc_recv(zfs_cmd_t *zc)
error = zfs_ioc_recv_impl(tofs, tosnap, origin, recvdprops, localprops,
NULL, zc->zc_guid, B_FALSE, zc->zc_cookie, &begin_record,
- zc->zc_cleanup_fd, &zc->zc_cookie, &zc->zc_obj,
- &zc->zc_action_handle, &errors);
+ &zc->zc_cookie, &zc->zc_obj, &errors);
nvlist_free(recvdprops);
nvlist_free(localprops);
@@ -5171,15 +5167,14 @@ zfs_ioc_recv(zfs_cmd_t *zc)
* "input_fd" -> file descriptor to read stream from (int32)
* (optional) "force" -> force flag (value ignored)
* (optional) "resumable" -> resumable flag (value ignored)
- * (optional) "cleanup_fd" -> cleanup-on-exit file descriptor
- * (optional) "action_handle" -> handle for this guid/ds mapping
+ * (optional) "cleanup_fd" -> unused
+ * (optional) "action_handle" -> unused
* (optional) "hidden_args" -> { "wkeydata" -> value }
* }
*
* outnvl: {
* "read_bytes" -> number of bytes read
* "error_flags" -> zprop_errflags_t
- * "action_handle" -> handle for this guid/ds mapping
* "errors" -> error for each unapplied received property (nvlist)
* }
*/
@@ -5212,11 +5207,9 @@ zfs_ioc_recv_new(const char *fsname, nvlist_t *innvl, nvlist_t *outnvl)
char tofs[ZFS_MAX_DATASET_NAME_LEN];
boolean_t force;
boolean_t resumable;
- uint64_t action_handle = 0;
uint64_t read_bytes = 0;
uint64_t errflags = 0;
int input_fd = -1;
- int cleanup_fd = -1;
int error;
snapname = fnvlist_lookup_string(innvl, "snapname");
@@ -5244,14 +5237,6 @@ zfs_ioc_recv_new(const char *fsname, nvlist_t *innvl, nvlist_t *outnvl)
force = nvlist_exists(innvl, "force");
resumable = nvlist_exists(innvl, "resumable");
- error = nvlist_lookup_int32(innvl, "cleanup_fd", &cleanup_fd);
- if (error && error != ENOENT)
- return (error);
-
- error = nvlist_lookup_uint64(innvl, "action_handle", &action_handle);
- if (error && error != ENOENT)
- return (error);
-
/* we still use "props" here for backwards compatibility */
error = nvlist_lookup_nvlist(innvl, "props", &recvprops);
if (error && error != ENOENT)
@@ -5266,12 +5251,11 @@ zfs_ioc_recv_new(const char *fsname, nvlist_t *innvl, nvlist_t *outnvl)
return (error);
error = zfs_ioc_recv_impl(tofs, tosnap, origin, recvprops, localprops,
- hidden_args, force, resumable, input_fd, begin_record, cleanup_fd,
- &read_bytes, &errflags, &action_handle, &errors);
+ hidden_args, force, resumable, input_fd, begin_record,
+ &read_bytes, &errflags, &errors);
fnvlist_add_uint64(outnvl, "read_bytes", read_bytes);
fnvlist_add_uint64(outnvl, "error_flags", errflags);
- fnvlist_add_uint64(outnvl, "action_handle", action_handle);
fnvlist_add_nvlist(outnvl, "errors", errors);
nvlist_free(errors);
diff --git a/module/zfs/zfs_onexit.c b/module/zfs/zfs_onexit.c
index bf86446d4..2a1332e71 100644
--- a/module/zfs/zfs_onexit.c
+++ b/module/zfs/zfs_onexit.c
@@ -20,7 +20,7 @@
*/
/*
* Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
- * Copyright (c) 2013 by Delphix. All rights reserved.
+ * Copyright (c) 2013, 2020 by Delphix. All rights reserved.
*/
#include <sys/types.h>
@@ -171,80 +171,3 @@ zfs_onexit_add_cb(minor_t minor, void (*func)(void *), void *data,
return (0);
}
-
-static zfs_onexit_action_node_t *
-zfs_onexit_find_cb(zfs_onexit_t *zo, uint64_t action_handle)
-{
- zfs_onexit_action_node_t *match;
- zfs_onexit_action_node_t *ap;
- list_t *l;
-
- ASSERT(MUTEX_HELD(&zo->zo_lock));
-
- match = (zfs_onexit_action_node_t *)(uintptr_t)action_handle;
- l = &zo->zo_actions;
- for (ap = list_head(l); ap != NULL; ap = list_next(l, ap)) {
- if (match == ap)
- break;
- }
- return (ap);
-}
-
-/*
- * Delete the callback, triggering it first if 'fire' is set.
- */
-int
-zfs_onexit_del_cb(minor_t minor, uint64_t action_handle, boolean_t fire)
-{
- zfs_onexit_t *zo;
- zfs_onexit_action_node_t *ap;
- int error;
-
- error = zfs_onexit_minor_to_state(minor, &zo);
- if (error)
- return (error);
-
- mutex_enter(&zo->zo_lock);
- ap = zfs_onexit_find_cb(zo, action_handle);
- if (ap != NULL) {
- list_remove(&zo->zo_actions, ap);
- mutex_exit(&zo->zo_lock);
- if (fire)
- ap->za_func(ap->za_data);
- kmem_free(ap, sizeof (zfs_onexit_action_node_t));
- } else {
- mutex_exit(&zo->zo_lock);
- error = SET_ERROR(ENOENT);
- }
-
- return (error);
-}
-
-/*
- * Return the data associated with this callback. This allows consumers
- * of the cleanup-on-exit interfaces to stash kernel data across system
- * calls, knowing that it will be cleaned up if the calling process exits.
- */
-int
-zfs_onexit_cb_data(minor_t minor, uint64_t action_handle, void **data)
-{
- zfs_onexit_t *zo;
- zfs_onexit_action_node_t *ap;
- int error;
-
- *data = NULL;
-
- error = zfs_onexit_minor_to_state(minor, &zo);
- if (error)
- return (error);
-
- mutex_enter(&zo->zo_lock);
- ap = zfs_onexit_find_cb(zo, action_handle);
- if (ap != NULL)
- *data = ap->za_data;
- else
- error = SET_ERROR(ENOENT);
- mutex_exit(&zo->zo_lock);
-
- return (error);
-}