From fbfda270d5bb249805a8fe2308c3cdc6d8869e80 Mon Sep 17 00:00:00 2001 From: Rob Norris Date: Thu, 5 Jun 2025 16:07:36 +1000 Subject: [PATCH] zcp_synctask: add zfs.sync.clone() Reviewed-by: Brian Behlendorf Reviewed-by: Alexander Motin Signed-off-by: Rob Norris Sponsored-by: https://despairlabs.com/sponsor/ Closes #17426 --- module/zfs/zcp_synctask.c | 44 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 44 insertions(+) diff --git a/module/zfs/zcp_synctask.c b/module/zfs/zcp_synctask.c index 28f734abf..ce3a4e8a9 100644 --- a/module/zfs/zcp_synctask.c +++ b/module/zfs/zcp_synctask.c @@ -18,6 +18,7 @@ * Copyright (c) 2016, 2017 by Delphix. All rights reserved. * Copyright (c) 2019, 2020 by Christian Schwarz. All rights reserved. * Copyright 2020 Joyent, Inc. + * Copyright (c) 2025, Rob Norris */ #include @@ -113,6 +114,48 @@ zcp_sync_task(lua_State *state, dsl_checkfunc_t *checkfunc, return (err); } +static int zcp_synctask_clone(lua_State *, boolean_t, nvlist_t *); +static const zcp_synctask_info_t zcp_synctask_clone_info = { + .name = "clone", + .func = zcp_synctask_clone, + .pargs = { + {.za_name = "snapshot", .za_lua_type = LUA_TSTRING }, + {.za_name = "newdataset", .za_lua_type = LUA_TSTRING }, + {NULL, 0} + }, + .kwargs = { + {NULL, 0} + }, + .space_check = ZFS_SPACE_CHECK_NORMAL, + .blocks_modified = 3 +}; +static int +zcp_synctask_clone(lua_State *state, boolean_t sync, nvlist_t *err_details) +{ + (void) err_details; + int err; + + zcp_run_info_t *ri = zcp_run_info(state); + dsl_dataset_clone_arg_t ddca = { + .ddca_origin = lua_tostring(state, 1), + .ddca_clone = lua_tostring(state, 2), + .ddca_cred = ri->zri_cred, + }; + + err = zcp_sync_task(state, dsl_dataset_clone_check, + dsl_dataset_clone_sync, &ddca, sync, ddca.ddca_origin); + + if (err == 0) + /* + * If the new dataset is a zvol, it will need a device + * node. Put it on the list to be considered in open context. + * We don't have to check the type here; if it's not a zvol, + * or has volmode=none, it will be ignored. + */ + fnvlist_add_boolean(ri->zri_new_zvols, ddca.ddca_clone); + + return (err); +} static int zcp_synctask_destroy(lua_State *, boolean_t, nvlist_t *); static const zcp_synctask_info_t zcp_synctask_destroy_info = { @@ -561,6 +604,7 @@ zcp_load_synctask_lib(lua_State *state, boolean_t sync) { const zcp_synctask_info_t *zcp_synctask_funcs[] = { &zcp_synctask_destroy_info, + &zcp_synctask_clone_info, &zcp_synctask_promote_info, &zcp_synctask_rollback_info, &zcp_synctask_snapshot_info,