Simplify resume token generation

* Improve naming.
* Reduce indentation.
* Avoid boilerplate logic duplication.

Reviewed-by: Brian Behlendorf <behlendorf1@llnl.gov>
Signed-off-by: Ryan Moeller <freqlabs@FreeBSD.org>
Closes #12967
This commit is contained in:
Ryan Moeller 2021-11-08 22:35:05 +00:00 committed by Brian Behlendorf
parent d1a38ee742
commit 15aa38690e
3 changed files with 141 additions and 179 deletions

View File

@ -385,8 +385,7 @@ int dsl_dataset_snap_lookup(dsl_dataset_t *ds, const char *name,
void dsl_dataset_dirty(dsl_dataset_t *ds, dmu_tx_t *tx); void dsl_dataset_dirty(dsl_dataset_t *ds, dmu_tx_t *tx);
int get_clones_stat_impl(dsl_dataset_t *ds, nvlist_t *val); int get_clones_stat_impl(dsl_dataset_t *ds, nvlist_t *val);
char *get_receive_resume_stats_impl(dsl_dataset_t *ds); char *get_receive_resume_token(dsl_dataset_t *ds);
char *get_child_receive_stats(dsl_dataset_t *ds);
uint64_t dsl_get_refratio(dsl_dataset_t *ds); uint64_t dsl_get_refratio(dsl_dataset_t *ds);
uint64_t dsl_get_logicalreferenced(dsl_dataset_t *ds); uint64_t dsl_get_logicalreferenced(dsl_dataset_t *ds);
uint64_t dsl_get_compressratio(dsl_dataset_t *ds); uint64_t dsl_get_compressratio(dsl_dataset_t *ds);

View File

@ -2331,16 +2331,13 @@ get_clones_stat(dsl_dataset_t *ds, nvlist_t *nv)
nvlist_free(propval); nvlist_free(propval);
} }
/* static char *
* Returns a string that represents the receive resume stats token. It should get_receive_resume_token_impl(dsl_dataset_t *ds)
* be freed with strfree().
*/
char *
get_receive_resume_stats_impl(dsl_dataset_t *ds)
{ {
dsl_pool_t *dp = ds->ds_dir->dd_pool; if (!dsl_dataset_has_resume_receive_state(ds))
return (NULL);
if (dsl_dataset_has_resume_receive_state(ds)) { dsl_pool_t *dp = ds->ds_dir->dd_pool;
char *str; char *str;
void *packed; void *packed;
uint8_t *compressed; uint8_t *compressed;
@ -2444,48 +2441,37 @@ get_receive_resume_stats_impl(dsl_dataset_t *ds)
kmem_free(compressed, packed_size); kmem_free(compressed, packed_size);
return (propval); return (propval);
} }
return (kmem_strdup(""));
}
/* /*
* Returns a string that represents the receive resume stats token of the * Returns a string that represents the receive resume state token. It should
* dataset's child. It should be freed with strfree(). * be freed with strfree(). NULL is returned if no resume state is present.
*/ */
char * char *
get_child_receive_stats(dsl_dataset_t *ds) get_receive_resume_token(dsl_dataset_t *ds)
{ {
char recvname[ZFS_MAX_DATASET_NAME_LEN + 6]; /*
* A failed "newfs" (e.g. full) resumable receive leaves
* the stats set on this dataset. Check here for the prop.
*/
char *token = get_receive_resume_token_impl(ds);
if (token != NULL)
return (token);
/*
* A failed incremental resumable receive leaves the
* stats set on our child named "%recv". Check the child
* for the prop.
*/
/* 6 extra bytes for /%recv */
char name[ZFS_MAX_DATASET_NAME_LEN + 6];
dsl_dataset_t *recv_ds; dsl_dataset_t *recv_ds;
dsl_dataset_name(ds, recvname); dsl_dataset_name(ds, name);
if (strlcat(recvname, "/", sizeof (recvname)) < if (strlcat(name, "/", sizeof (name)) < sizeof (name) &&
sizeof (recvname) && strlcat(name, recv_clone_name, sizeof (name)) < sizeof (name) &&
strlcat(recvname, recv_clone_name, sizeof (recvname)) < dsl_dataset_hold(ds->ds_dir->dd_pool, name, FTAG, &recv_ds) == 0) {
sizeof (recvname) && token = get_receive_resume_token_impl(recv_ds);
dsl_dataset_hold(ds->ds_dir->dd_pool, recvname, FTAG,
&recv_ds) == 0) {
char *propval = get_receive_resume_stats_impl(recv_ds);
dsl_dataset_rele(recv_ds, FTAG); dsl_dataset_rele(recv_ds, FTAG);
return (propval);
} }
return (kmem_strdup("")); return (token);
}
static void
get_receive_resume_stats(dsl_dataset_t *ds, nvlist_t *nv)
{
char *propval = get_receive_resume_stats_impl(ds);
if (strcmp(propval, "") != 0) {
dsl_prop_nvlist_add_string(nv,
ZFS_PROP_RECEIVE_RESUME_TOKEN, propval);
} else {
char *childval = get_child_receive_stats(ds);
if (strcmp(childval, "") != 0) {
dsl_prop_nvlist_add_string(nv,
ZFS_PROP_RECEIVE_RESUME_TOKEN, childval);
}
kmem_strfree(childval);
}
kmem_strfree(propval);
} }
uint64_t uint64_t
@ -2761,7 +2747,7 @@ dsl_get_mountpoint(dsl_dataset_t *ds, const char *dsname, char *value,
void void
dsl_dataset_stats(dsl_dataset_t *ds, nvlist_t *nv) dsl_dataset_stats(dsl_dataset_t *ds, nvlist_t *nv)
{ {
dsl_pool_t *dp = ds->ds_dir->dd_pool; dsl_pool_t *dp __maybe_unused = ds->ds_dir->dd_pool;
ASSERT(dsl_pool_config_held(dp)); ASSERT(dsl_pool_config_held(dp));
@ -2823,28 +2809,11 @@ dsl_dataset_stats(dsl_dataset_t *ds, nvlist_t *nv)
} }
if (!dsl_dataset_is_snapshot(ds)) { if (!dsl_dataset_is_snapshot(ds)) {
/* char *token = get_receive_resume_token(ds);
* A failed "newfs" (e.g. full) resumable receive leaves if (token != NULL) {
* the stats set on this dataset. Check here for the prop. dsl_prop_nvlist_add_string(nv,
*/ ZFS_PROP_RECEIVE_RESUME_TOKEN, token);
get_receive_resume_stats(ds, nv); kmem_strfree(token);
/*
* A failed incremental resumable receive leaves the
* stats set on our child named "%recv". Check the child
* for the prop.
*/
/* 6 extra bytes for /%recv */
char recvname[ZFS_MAX_DATASET_NAME_LEN + 6];
dsl_dataset_t *recv_ds;
dsl_dataset_name(ds, recvname);
if (strlcat(recvname, "/", sizeof (recvname)) <
sizeof (recvname) &&
strlcat(recvname, recv_clone_name, sizeof (recvname)) <
sizeof (recvname) &&
dsl_dataset_hold(dp, recvname, FTAG, &recv_ds) == 0) {
get_receive_resume_stats(recv_ds, nv);
dsl_dataset_rele(recv_ds, FTAG);
} }
} }
} }

View File

@ -344,19 +344,13 @@ get_special_prop(lua_State *state, dsl_dataset_t *ds, const char *dsname,
} }
break; break;
case ZFS_PROP_RECEIVE_RESUME_TOKEN: { case ZFS_PROP_RECEIVE_RESUME_TOKEN: {
char *token = get_receive_resume_stats_impl(ds); char *token = get_receive_resume_token(ds);
if (token != NULL) {
(void) strlcpy(strval, token, ZAP_MAXVALUELEN); (void) strlcpy(strval, token, ZAP_MAXVALUELEN);
if (strcmp(strval, "") == 0) {
char *childval = get_child_receive_stats(ds);
(void) strlcpy(strval, childval, ZAP_MAXVALUELEN);
if (strcmp(strval, "") == 0)
error = ENOENT;
kmem_strfree(childval);
}
kmem_strfree(token); kmem_strfree(token);
} else {
error = ENOENT;
}
break; break;
} }
case ZFS_PROP_VOLSIZE: case ZFS_PROP_VOLSIZE: