mirror of
https://git.proxmox.com/git/mirror_zfs.git
synced 2024-12-27 19:39:35 +03:00
Fix stack dmu_objset_snapshot()
Reduce stack usage by 276 bytes by moving the snaparg struct from the stack to the heap. We have limited stack space we must not waste. Signed-off-by: Brian Behlendorf <behlendorf1@llnl.gov>
This commit is contained in:
parent
fc5bb51f08
commit
a8ac8e715e
@ -946,16 +946,19 @@ dmu_objset_snapshot(char *fsname, char *snapname, char *tag,
|
|||||||
nvlist_t *props, boolean_t recursive, boolean_t temporary, int cleanup_fd)
|
nvlist_t *props, boolean_t recursive, boolean_t temporary, int cleanup_fd)
|
||||||
{
|
{
|
||||||
dsl_sync_task_t *dst;
|
dsl_sync_task_t *dst;
|
||||||
struct snaparg sn;
|
struct snaparg *sn;
|
||||||
spa_t *spa;
|
spa_t *spa;
|
||||||
minor_t minor;
|
minor_t minor;
|
||||||
int err;
|
int err;
|
||||||
|
|
||||||
(void) strcpy(sn.failed, fsname);
|
sn = kmem_alloc(sizeof (struct snaparg), KM_SLEEP);
|
||||||
|
(void) strcpy(sn->failed, fsname);
|
||||||
|
|
||||||
err = spa_open(fsname, &spa, FTAG);
|
err = spa_open(fsname, &spa, FTAG);
|
||||||
if (err)
|
if (err) {
|
||||||
|
kmem_free(sn, sizeof (struct snaparg));
|
||||||
return (err);
|
return (err);
|
||||||
|
}
|
||||||
|
|
||||||
if (temporary) {
|
if (temporary) {
|
||||||
if (cleanup_fd < 0) {
|
if (cleanup_fd < 0) {
|
||||||
@ -968,46 +971,47 @@ dmu_objset_snapshot(char *fsname, char *snapname, char *tag,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
sn.dstg = dsl_sync_task_group_create(spa_get_dsl(spa));
|
sn->dstg = dsl_sync_task_group_create(spa_get_dsl(spa));
|
||||||
sn.snapname = snapname;
|
sn->snapname = snapname;
|
||||||
sn.htag = tag;
|
sn->htag = tag;
|
||||||
sn.props = props;
|
sn->props = props;
|
||||||
sn.recursive = recursive;
|
sn->recursive = recursive;
|
||||||
sn.needsuspend = (spa_version(spa) < SPA_VERSION_FAST_SNAP);
|
sn->needsuspend = (spa_version(spa) < SPA_VERSION_FAST_SNAP);
|
||||||
sn.temporary = temporary;
|
sn->temporary = temporary;
|
||||||
sn.ha = NULL;
|
sn->ha = NULL;
|
||||||
sn.newds = NULL;
|
sn->newds = NULL;
|
||||||
|
|
||||||
if (recursive) {
|
if (recursive) {
|
||||||
err = dmu_objset_find(fsname,
|
err = dmu_objset_find(fsname,
|
||||||
dmu_objset_snapshot_one, &sn, DS_FIND_CHILDREN);
|
dmu_objset_snapshot_one, sn, DS_FIND_CHILDREN);
|
||||||
} else {
|
} else {
|
||||||
err = dmu_objset_snapshot_one(fsname, &sn);
|
err = dmu_objset_snapshot_one(fsname, sn);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (err == 0)
|
if (err == 0)
|
||||||
err = dsl_sync_task_group_wait(sn.dstg);
|
err = dsl_sync_task_group_wait(sn->dstg);
|
||||||
|
|
||||||
for (dst = list_head(&sn.dstg->dstg_tasks); dst;
|
for (dst = list_head(&sn->dstg->dstg_tasks); dst;
|
||||||
dst = list_next(&sn.dstg->dstg_tasks, dst)) {
|
dst = list_next(&sn->dstg->dstg_tasks, dst)) {
|
||||||
objset_t *os = dst->dst_arg1;
|
objset_t *os = dst->dst_arg1;
|
||||||
dsl_dataset_t *ds = os->os_dsl_dataset;
|
dsl_dataset_t *ds = os->os_dsl_dataset;
|
||||||
if (dst->dst_err) {
|
if (dst->dst_err) {
|
||||||
dsl_dataset_name(ds, sn.failed);
|
dsl_dataset_name(ds, sn->failed);
|
||||||
} else if (temporary) {
|
} else if (temporary) {
|
||||||
dsl_register_onexit_hold_cleanup(sn.newds, tag, minor);
|
dsl_register_onexit_hold_cleanup(sn->newds, tag, minor);
|
||||||
}
|
}
|
||||||
if (sn.needsuspend)
|
if (sn->needsuspend)
|
||||||
zil_resume(dmu_objset_zil(os));
|
zil_resume(dmu_objset_zil(os));
|
||||||
dmu_objset_rele(os, &sn);
|
dmu_objset_rele(os, sn);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (err)
|
if (err)
|
||||||
(void) strcpy(fsname, sn.failed);
|
(void) strcpy(fsname, sn->failed);
|
||||||
if (temporary)
|
if (temporary)
|
||||||
zfs_onexit_fd_rele(cleanup_fd);
|
zfs_onexit_fd_rele(cleanup_fd);
|
||||||
dsl_sync_task_group_destroy(sn.dstg);
|
dsl_sync_task_group_destroy(sn->dstg);
|
||||||
spa_close(spa, FTAG);
|
spa_close(spa, FTAG);
|
||||||
|
kmem_free(sn, sizeof (struct snaparg));
|
||||||
return (err);
|
return (err);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user