summaryrefslogtreecommitdiffstats
path: root/module
diff options
context:
space:
mode:
authorBrian Behlendorf <[email protected]>2010-08-26 10:52:23 -0700
committerBrian Behlendorf <[email protected]>2010-08-31 08:38:47 -0700
commita8ac8e715e50e56b5e907007ef70f39301a4d984 (patch)
tree74e498567d99840f6f67cc3bac8cbf0978715e5b /module
parentfc5bb51f08a6c91ff9ad3559d0266eeeab0b1f61 (diff)
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 <[email protected]>
Diffstat (limited to 'module')
-rw-r--r--module/zfs/dmu_objset.c50
1 files changed, 27 insertions, 23 deletions
diff --git a/module/zfs/dmu_objset.c b/module/zfs/dmu_objset.c
index 2d06897db..1dcfb02c5 100644
--- a/module/zfs/dmu_objset.c
+++ b/module/zfs/dmu_objset.c
@@ -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)
{
dsl_sync_task_t *dst;
- struct snaparg sn;
+ struct snaparg *sn;
spa_t *spa;
minor_t minor;
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);
- if (err)
+ if (err) {
+ kmem_free(sn, sizeof (struct snaparg));
return (err);
+ }
if (temporary) {
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.snapname = snapname;
- sn.htag = tag;
- sn.props = props;
- sn.recursive = recursive;
- sn.needsuspend = (spa_version(spa) < SPA_VERSION_FAST_SNAP);
- sn.temporary = temporary;
- sn.ha = NULL;
- sn.newds = NULL;
+ sn->dstg = dsl_sync_task_group_create(spa_get_dsl(spa));
+ sn->snapname = snapname;
+ sn->htag = tag;
+ sn->props = props;
+ sn->recursive = recursive;
+ sn->needsuspend = (spa_version(spa) < SPA_VERSION_FAST_SNAP);
+ sn->temporary = temporary;
+ sn->ha = NULL;
+ sn->newds = NULL;
if (recursive) {
err = dmu_objset_find(fsname,
- dmu_objset_snapshot_one, &sn, DS_FIND_CHILDREN);
+ dmu_objset_snapshot_one, sn, DS_FIND_CHILDREN);
} else {
- err = dmu_objset_snapshot_one(fsname, &sn);
+ err = dmu_objset_snapshot_one(fsname, sn);
}
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;
- dst = list_next(&sn.dstg->dstg_tasks, dst)) {
+ for (dst = list_head(&sn->dstg->dstg_tasks); dst;
+ dst = list_next(&sn->dstg->dstg_tasks, dst)) {
objset_t *os = dst->dst_arg1;
dsl_dataset_t *ds = os->os_dsl_dataset;
if (dst->dst_err) {
- dsl_dataset_name(ds, sn.failed);
+ dsl_dataset_name(ds, sn->failed);
} 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));
- dmu_objset_rele(os, &sn);
+ dmu_objset_rele(os, sn);
}
if (err)
- (void) strcpy(fsname, sn.failed);
+ (void) strcpy(fsname, sn->failed);
if (temporary)
zfs_onexit_fd_rele(cleanup_fd);
- dsl_sync_task_group_destroy(sn.dstg);
+ dsl_sync_task_group_destroy(sn->dstg);
spa_close(spa, FTAG);
+ kmem_free(sn, sizeof (struct snaparg));
return (err);
}