Retire send space estimation via ZFS_IOC_SEND
Add a small wrapper around libzfs_core`lzc_send_space() to libzfs so that every legacy ZFS_IOC_SEND consumer, along with their userland counterpart estimate_ioctl(), can leverage ZFS_IOC_SEND_SPACE to request send space estimation. The legacy functionality in zfs_ioc_send() is left untouched for compatibility purposes. Reviewed by: Thomas Caputi <tcaputi@datto.com> Reviewed-by: Brian Behlendorf <behlendorf1@llnl.gov> Signed-off-by: loli10K <ezomori.nozomu@gmail.com> Closes #6029
This commit is contained in:
parent
1afc54f7f4
commit
cf7684bc8d
|
@ -1013,39 +1013,32 @@ typedef struct send_dump_data {
|
|||
} send_dump_data_t;
|
||||
|
||||
static int
|
||||
estimate_ioctl(zfs_handle_t *zhp, uint64_t fromsnap_obj,
|
||||
boolean_t fromorigin, enum lzc_send_flags flags, uint64_t *sizep)
|
||||
zfs_send_space(zfs_handle_t *zhp, const char *snapname, const char *from,
|
||||
enum lzc_send_flags flags, uint64_t *spacep)
|
||||
{
|
||||
zfs_cmd_t zc = {"\0"};
|
||||
libzfs_handle_t *hdl = zhp->zfs_hdl;
|
||||
int error;
|
||||
|
||||
assert(zhp->zfs_type == ZFS_TYPE_SNAPSHOT);
|
||||
assert(fromsnap_obj == 0 || !fromorigin);
|
||||
assert(snapname != NULL);
|
||||
error = lzc_send_space(snapname, from, flags, spacep);
|
||||
|
||||
(void) strlcpy(zc.zc_name, zhp->zfs_name, sizeof (zc.zc_name));
|
||||
zc.zc_obj = fromorigin;
|
||||
zc.zc_sendobj = zfs_prop_get_int(zhp, ZFS_PROP_OBJSETID);
|
||||
zc.zc_fromobj = fromsnap_obj;
|
||||
zc.zc_guid = 1; /* estimate flag */
|
||||
zc.zc_flags = flags;
|
||||
|
||||
if (zfs_ioctl(zhp->zfs_hdl, ZFS_IOC_SEND, &zc) != 0) {
|
||||
if (error != 0) {
|
||||
char errbuf[1024];
|
||||
(void) snprintf(errbuf, sizeof (errbuf), dgettext(TEXT_DOMAIN,
|
||||
"warning: cannot estimate space for '%s'"), zhp->zfs_name);
|
||||
"warning: cannot estimate space for '%s'"), snapname);
|
||||
|
||||
switch (errno) {
|
||||
switch (error) {
|
||||
case EXDEV:
|
||||
zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
|
||||
"not an earlier snapshot from the same fs"));
|
||||
return (zfs_error(hdl, EZFS_CROSSTARGET, errbuf));
|
||||
|
||||
case ENOENT:
|
||||
if (zfs_dataset_exists(hdl, zc.zc_name,
|
||||
if (zfs_dataset_exists(hdl, snapname,
|
||||
ZFS_TYPE_SNAPSHOT)) {
|
||||
zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
|
||||
"incremental source (@%s) does not exist"),
|
||||
zc.zc_value);
|
||||
"incremental source (%s) does not exist"),
|
||||
snapname);
|
||||
}
|
||||
return (zfs_error(hdl, EZFS_NOENT, errbuf));
|
||||
|
||||
|
@ -1060,16 +1053,15 @@ estimate_ioctl(zfs_handle_t *zhp, uint64_t fromsnap_obj,
|
|||
case ERANGE:
|
||||
case EFAULT:
|
||||
case EROFS:
|
||||
zfs_error_aux(hdl, strerror(errno));
|
||||
case EINVAL:
|
||||
zfs_error_aux(hdl, strerror(error));
|
||||
return (zfs_error(hdl, EZFS_BADBACKUP, errbuf));
|
||||
|
||||
default:
|
||||
return (zfs_standard_error(hdl, errno, errbuf));
|
||||
return (zfs_standard_error(hdl, error, errbuf));
|
||||
}
|
||||
}
|
||||
|
||||
*sizep = zc.zc_objset_type;
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
|
@ -1355,12 +1347,21 @@ dump_snapshot(zfs_handle_t *zhp, void *arg)
|
|||
|
||||
if (sdd->verbose) {
|
||||
uint64_t size = 0;
|
||||
(void) estimate_ioctl(zhp, sdd->prevsnap_obj,
|
||||
fromorigin, flags, &size);
|
||||
char fromds[ZFS_MAX_DATASET_NAME_LEN];
|
||||
|
||||
send_print_verbose(fout, zhp->zfs_name,
|
||||
sdd->prevsnap[0] ? sdd->prevsnap : NULL,
|
||||
size, sdd->parsable);
|
||||
if (sdd->prevsnap[0] != '\0') {
|
||||
(void) strlcpy(fromds, zhp->zfs_name, sizeof (fromds));
|
||||
*(strchr(fromds, '@') + 1) = '\0';
|
||||
(void) strlcat(fromds, sdd->prevsnap, sizeof (fromds));
|
||||
}
|
||||
if (zfs_send_space(zhp, zhp->zfs_name,
|
||||
sdd->prevsnap[0] ? fromds : NULL, flags, &size) != 0) {
|
||||
size = 0; /* cannot estimate send space */
|
||||
} else {
|
||||
send_print_verbose(fout, zhp->zfs_name,
|
||||
sdd->prevsnap[0] ? sdd->prevsnap : NULL,
|
||||
size, sdd->parsable);
|
||||
}
|
||||
sdd->size += size;
|
||||
}
|
||||
|
||||
|
|
|
@ -590,6 +590,8 @@ lzc_send_space(const char *snapname, const char *from,
|
|||
fnvlist_add_boolean(args, "embedok");
|
||||
if (flags & LZC_SEND_FLAG_COMPRESS)
|
||||
fnvlist_add_boolean(args, "compressok");
|
||||
if (flags & LZC_SEND_FLAG_RAW)
|
||||
fnvlist_add_boolean(args, "rawok");
|
||||
err = lzc_ioctl(ZFS_IOC_SEND_SPACE, snapname, args, &result);
|
||||
nvlist_free(args);
|
||||
if (err == 0)
|
||||
|
|
|
@ -4758,6 +4758,9 @@ zfs_ioc_recv_new(const char *fsname, nvlist_t *innvl, nvlist_t *outnvl)
|
|||
*
|
||||
* outputs:
|
||||
* zc_objset_type estimated size, if zc_guid is set
|
||||
*
|
||||
* NOTE: This is no longer the preferred interface, any new functionality
|
||||
* should be added to zfs_ioc_send_new() instead.
|
||||
*/
|
||||
static int
|
||||
zfs_ioc_send(zfs_cmd_t *zc)
|
||||
|
@ -5876,6 +5879,8 @@ zfs_ioc_send_new(const char *snapname, nvlist_t *innvl, nvlist_t *outnvl)
|
|||
* presence indicates DRR_WRITE_EMBEDDED records are permitted
|
||||
* (optional) "compressok" -> (value ignored)
|
||||
* presence indicates compressed DRR_WRITE records are permitted
|
||||
* (optional) "rawok" -> (value ignored)
|
||||
* presence indicates raw encrypted records should be used.
|
||||
* }
|
||||
*
|
||||
* outnvl: {
|
||||
|
|
Loading…
Reference in New Issue