Skip to content

Commit 3d45fdd

Browse files
ahrensbehlendorf
authored andcommitted
Illumos 4951 - ZFS administrative commands should use reserved space
4951 ZFS administrative commands should use reserved space, not with ENOSPC Reviewed by: John Kennedy <john.kennedy@delphix.com> Reviewed by: George Wilson <george.wilson@delphix.com> Reviewed by: Christopher Siden <christopher.siden@delphix.com> Reviewed by: Dan McDonald <danmcd@omniti.com> Approved by: Garrett D'Amore <garrett@damore.org> References: https://www.illumos.org/issues/4373 illumos/illumos-gate@7d46dc6 Ported by: Brian Behlendorf <behlendorf1@llnl.gov>
1 parent cfec5b1 commit 3d45fdd

18 files changed

+164
-67
lines changed

cmd/zfs/zfs_main.c

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@
2121

2222
/*
2323
* Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
24-
* Copyright (c) 2013 by Delphix. All rights reserved.
24+
* Copyright (c) 2011, 2014 by Delphix. All rights reserved.
2525
* Copyright (c) 2012, Joyent, Inc. All rights reserved.
2626
* Copyright (c) 2013 Steven Hartland. All rights reserved.
2727
* Copyright 2013 Nexenta Systems, Inc. All rights reserved.
@@ -6636,6 +6636,9 @@ zfs_do_bookmark(int argc, char **argv)
66366636
case ENOTSUP:
66376637
err_msg = "bookmark feature not enabled";
66386638
break;
6639+
case ENOSPC:
6640+
err_msg = "out of space";
6641+
break;
66396642
default:
66406643
err_msg = "unknown error";
66416644
break;
@@ -6644,7 +6647,7 @@ zfs_do_bookmark(int argc, char **argv)
66446647
dgettext(TEXT_DOMAIN, err_msg));
66456648
}
66466649

6647-
return (ret);
6650+
return (ret != 0);
66486651

66496652
usage:
66506653
usage(B_FALSE);

cmd/zhack/zhack.c

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@
2020
*/
2121

2222
/*
23-
* Copyright (c) 2013 by Delphix. All rights reserved.
23+
* Copyright (c) 2011, 2014 by Delphix. All rights reserved.
2424
* Copyright (c) 2013 Steven Hartland. All rights reserved.
2525
*/
2626

@@ -362,7 +362,7 @@ zhack_do_feature_enable(int argc, char **argv)
362362
feature.fi_guid);
363363

364364
VERIFY0(dsl_sync_task(spa_name(spa), NULL,
365-
zhack_feature_enable_sync, &feature, 5));
365+
zhack_feature_enable_sync, &feature, 5, ZFS_SPACE_CHECK_NORMAL));
366366

367367
spa_close(spa, FTAG);
368368

@@ -473,7 +473,8 @@ zhack_do_feature_ref(int argc, char **argv)
473473
}
474474

475475
VERIFY0(dsl_sync_task(spa_name(spa), NULL,
476-
decr ? feature_decr_sync : feature_incr_sync, &feature, 5));
476+
decr ? feature_decr_sync : feature_incr_sync, &feature,
477+
5, ZFS_SPACE_CHECK_NORMAL));
477478

478479
spa_close(spa, FTAG);
479480
}

include/sys/dsl_synctask.h

Lines changed: 36 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@
2020
*/
2121
/*
2222
* Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
23-
* Copyright (c) 2012 by Delphix. All rights reserved.
23+
* Copyright (c) 2012, 2014 by Delphix. All rights reserved.
2424
*/
2525

2626
#ifndef _SYS_DSL_SYNCTASK_H
@@ -38,23 +38,53 @@ struct dsl_pool;
3838
typedef int (dsl_checkfunc_t)(void *, dmu_tx_t *);
3939
typedef void (dsl_syncfunc_t)(void *, dmu_tx_t *);
4040

41+
typedef enum zfs_space_check {
42+
/*
43+
* Normal space check: if there is less than 3.2% free space,
44+
* the operation will fail. Operations which are logically
45+
* creating things should use this (e.g. "zfs create", "zfs snapshot").
46+
* User writes (via the ZPL / ZVOL) also fail at this point.
47+
*/
48+
ZFS_SPACE_CHECK_NORMAL,
49+
50+
/*
51+
* Space check allows use of half the slop space. If there
52+
* is less than 1.6% free space, the operation will fail. Most
53+
* operations should use this (e.g. "zfs set", "zfs rename"),
54+
* because we want them to succeed even after user writes are failing,
55+
* so that they can be used as part of the space recovery process.
56+
*/
57+
ZFS_SPACE_CHECK_RESERVED,
58+
59+
/*
60+
* No space check is performed. Only operations which we expect to
61+
* result in a net reduction in space should use this
62+
* (e.g. "zfs destroy". Setting quotas & reservations also uses
63+
* this because it needs to circumvent the quota/reservation checks).
64+
*
65+
* See also the comments above spa_slop_shift.
66+
*/
67+
ZFS_SPACE_CHECK_NONE,
68+
} zfs_space_check_t;
69+
4170
typedef struct dsl_sync_task {
4271
txg_node_t dst_node;
4372
struct dsl_pool *dst_pool;
4473
uint64_t dst_txg;
4574
int dst_space;
75+
zfs_space_check_t dst_space_check;
4676
dsl_checkfunc_t *dst_checkfunc;
4777
dsl_syncfunc_t *dst_syncfunc;
4878
void *dst_arg;
4979
int dst_error;
5080
boolean_t dst_nowaiter;
5181
} dsl_sync_task_t;
5282

53-
void dsl_sync_task_sync(dsl_sync_task_t *dst, dmu_tx_t *tx);
54-
int dsl_sync_task(const char *pool, dsl_checkfunc_t *checkfunc,
55-
dsl_syncfunc_t *syncfunc, void *arg, int blocks_modified);
56-
void dsl_sync_task_nowait(struct dsl_pool *dp, dsl_syncfunc_t *syncfunc,
57-
void *arg, int blocks_modified, dmu_tx_t *tx);
83+
void dsl_sync_task_sync(dsl_sync_task_t *, dmu_tx_t *);
84+
int dsl_sync_task(const char *, dsl_checkfunc_t *,
85+
dsl_syncfunc_t *, void *, int, zfs_space_check_t);
86+
void dsl_sync_task_nowait(struct dsl_pool *, dsl_syncfunc_t *,
87+
void *, int, zfs_space_check_t, dmu_tx_t *);
5888

5989
#ifdef __cplusplus
6090
}

module/zfs/dmu_objset.c

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -865,7 +865,8 @@ dmu_objset_create(const char *name, dmu_objset_type_t type, uint64_t flags,
865865
doca.doca_type = type;
866866

867867
return (dsl_sync_task(name,
868-
dmu_objset_create_check, dmu_objset_create_sync, &doca, 5));
868+
dmu_objset_create_check, dmu_objset_create_sync, &doca,
869+
5, ZFS_SPACE_CHECK_NORMAL));
869870
}
870871

871872
typedef struct dmu_objset_clone_arg {
@@ -964,7 +965,8 @@ dmu_objset_clone(const char *clone, const char *origin)
964965
doca.doca_cred = CRED();
965966

966967
return (dsl_sync_task(clone,
967-
dmu_objset_clone_check, dmu_objset_clone_sync, &doca, 5));
968+
dmu_objset_clone_check, dmu_objset_clone_sync, &doca,
969+
5, ZFS_SPACE_CHECK_NORMAL));
968970
}
969971

970972
int

module/zfs/dmu_send.c

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1191,7 +1191,7 @@ dmu_recv_begin(char *tofs, char *tosnap, struct drr_begin *drrb,
11911191
drba.drba_cred = CRED();
11921192

11931193
return (dsl_sync_task(tofs, dmu_recv_begin_check, dmu_recv_begin_sync,
1194-
&drba, 5));
1194+
&drba, 5, ZFS_SPACE_CHECK_NORMAL));
11951195
}
11961196

11971197
struct restorearg {
@@ -2108,7 +2108,7 @@ dmu_recv_existing_end(dmu_recv_cookie_t *drc)
21082108

21092109
error = dsl_sync_task(drc->drc_tofs,
21102110
dmu_recv_end_check, dmu_recv_end_sync, drc,
2111-
dmu_recv_end_modified_blocks);
2111+
dmu_recv_end_modified_blocks, ZFS_SPACE_CHECK_NORMAL);
21122112

21132113
if (error != 0)
21142114
dmu_recv_cleanup_ds(drc);
@@ -2122,7 +2122,7 @@ dmu_recv_new_end(dmu_recv_cookie_t *drc)
21222122

21232123
error = dsl_sync_task(drc->drc_tofs,
21242124
dmu_recv_end_check, dmu_recv_end_sync, drc,
2125-
dmu_recv_end_modified_blocks);
2125+
dmu_recv_end_modified_blocks, ZFS_SPACE_CHECK_NORMAL);
21262126

21272127
if (error != 0) {
21282128
dmu_recv_cleanup_ds(drc);

module/zfs/dsl_bookmark.c

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313
* CDDL HEADER END
1414
*/
1515
/*
16-
* Copyright (c) 2013 by Delphix. All rights reserved.
16+
* Copyright (c) 2013, 2014 by Delphix. All rights reserved.
1717
*/
1818

1919
#include <sys/zfs_context.h>
@@ -249,7 +249,8 @@ dsl_bookmark_create(nvlist_t *bmarks, nvlist_t *errors)
249249
dbca.dbca_errors = errors;
250250

251251
return (dsl_sync_task(nvpair_name(pair), dsl_bookmark_create_check,
252-
dsl_bookmark_create_sync, &dbca, fnvlist_num_pairs(bmarks)));
252+
dsl_bookmark_create_sync, &dbca,
253+
fnvlist_num_pairs(bmarks), ZFS_SPACE_CHECK_NORMAL));
253254
}
254255

255256
int
@@ -454,7 +455,8 @@ dsl_bookmark_destroy(nvlist_t *bmarks, nvlist_t *errors)
454455
dbda.dbda_success = fnvlist_alloc();
455456

456457
rv = dsl_sync_task(nvpair_name(pair), dsl_bookmark_destroy_check,
457-
dsl_bookmark_destroy_sync, &dbda, fnvlist_num_pairs(bmarks));
458+
dsl_bookmark_destroy_sync, &dbda, fnvlist_num_pairs(bmarks),
459+
ZFS_SPACE_CHECK_RESERVED);
458460
fnvlist_free(dbda.dbda_success);
459461
return (rv);
460462
}

module/zfs/dsl_dataset.c

Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1406,7 +1406,7 @@ dsl_dataset_snapshot(nvlist_t *snaps, nvlist_t *props, nvlist_t *errors)
14061406
if (error == 0) {
14071407
error = dsl_sync_task(firstname, dsl_dataset_snapshot_check,
14081408
dsl_dataset_snapshot_sync, &ddsa,
1409-
fnvlist_num_pairs(snaps) * 3);
1409+
fnvlist_num_pairs(snaps) * 3, ZFS_SPACE_CHECK_NORMAL);
14101410
}
14111411

14121412
if (suspended != NULL) {
@@ -1518,7 +1518,7 @@ dsl_dataset_snapshot_tmp(const char *fsname, const char *snapname,
15181518
}
15191519

15201520
error = dsl_sync_task(fsname, dsl_dataset_snapshot_tmp_check,
1521-
dsl_dataset_snapshot_tmp_sync, &ddsta, 3);
1521+
dsl_dataset_snapshot_tmp_sync, &ddsta, 3, ZFS_SPACE_CHECK_RESERVED);
15221522

15231523
if (needsuspend)
15241524
zil_resume(cookie);
@@ -1874,7 +1874,8 @@ dsl_dataset_rename_snapshot(const char *fsname,
18741874
ddrsa.ddrsa_recursive = recursive;
18751875

18761876
error = dsl_sync_task(fsname, dsl_dataset_rename_snapshot_check,
1877-
dsl_dataset_rename_snapshot_sync, &ddrsa, 1);
1877+
dsl_dataset_rename_snapshot_sync, &ddrsa,
1878+
1, ZFS_SPACE_CHECK_RESERVED);
18781879

18791880
if (error)
18801881
return (SET_ERROR(error));
@@ -2064,7 +2065,8 @@ dsl_dataset_rollback(const char *fsname, void *owner, nvlist_t *result)
20642065
ddra.ddra_result = result;
20652066

20662067
return (dsl_sync_task(fsname, dsl_dataset_rollback_check,
2067-
dsl_dataset_rollback_sync, &ddra, 1));
2068+
dsl_dataset_rollback_sync, &ddra,
2069+
1, ZFS_SPACE_CHECK_RESERVED));
20682070
}
20692071

20702072
struct promotenode {
@@ -2595,7 +2597,8 @@ dsl_dataset_promote(const char *name, char *conflsnap)
25952597
ddpa.cr = CRED();
25962598

25972599
return (dsl_sync_task(name, dsl_dataset_promote_check,
2598-
dsl_dataset_promote_sync, &ddpa, 2 + numsnaps));
2600+
dsl_dataset_promote_sync, &ddpa,
2601+
2 + numsnaps, ZFS_SPACE_CHECK_RESERVED));
25992602
}
26002603

26012604
int
@@ -2949,7 +2952,7 @@ dsl_dataset_set_refquota(const char *dsname, zprop_source_t source,
29492952
ddsqra.ddsqra_value = refquota;
29502953

29512954
return (dsl_sync_task(dsname, dsl_dataset_set_refquota_check,
2952-
dsl_dataset_set_refquota_sync, &ddsqra, 0));
2955+
dsl_dataset_set_refquota_sync, &ddsqra, 0, ZFS_SPACE_CHECK_NONE));
29532956
}
29542957

29552958
static int
@@ -3064,7 +3067,8 @@ dsl_dataset_set_refreservation(const char *dsname, zprop_source_t source,
30643067
ddsqra.ddsqra_value = refreservation;
30653068

30663069
return (dsl_sync_task(dsname, dsl_dataset_set_refreservation_check,
3067-
dsl_dataset_set_refreservation_sync, &ddsqra, 0));
3070+
dsl_dataset_set_refreservation_sync, &ddsqra,
3071+
0, ZFS_SPACE_CHECK_NONE));
30683072
}
30693073

30703074
/*

module/zfs/dsl_deleg.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@
2020
*/
2121
/*
2222
* Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
23-
* Copyright (c) 2013 by Delphix. All rights reserved.
23+
* Copyright (c) 2011, 2014 by Delphix. All rights reserved.
2424
*/
2525

2626
/*
@@ -282,7 +282,7 @@ dsl_deleg_set(const char *ddname, nvlist_t *nvp, boolean_t unset)
282282

283283
return (dsl_sync_task(ddname, dsl_deleg_check,
284284
unset ? dsl_deleg_unset_sync : dsl_deleg_set_sync,
285-
&dda, fnvlist_num_pairs(nvp)));
285+
&dda, fnvlist_num_pairs(nvp), ZFS_SPACE_CHECK_RESERVED));
286286
}
287287

288288
/*

module/zfs/dsl_destroy.c

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -520,7 +520,7 @@ dsl_destroy_snapshots_nvl(nvlist_t *snaps, boolean_t defer,
520520

521521
error = dsl_sync_task(nvpair_name(pair),
522522
dsl_destroy_snapshot_check, dsl_destroy_snapshot_sync,
523-
&dsda, 0);
523+
&dsda, 0, ZFS_SPACE_CHECK_NONE);
524524
fnvlist_free(dsda.dsda_successful_snaps);
525525

526526
return (error);
@@ -918,7 +918,8 @@ dsl_destroy_head(const char *name)
918918
objset_t *os;
919919

920920
error = dsl_sync_task(name, dsl_destroy_head_check,
921-
dsl_destroy_head_begin_sync, &ddha, 0);
921+
dsl_destroy_head_begin_sync, &ddha,
922+
0, ZFS_SPACE_CHECK_NONE);
922923
if (error != 0)
923924
return (error);
924925

@@ -944,7 +945,7 @@ dsl_destroy_head(const char *name)
944945
}
945946

946947
return (dsl_sync_task(name, dsl_destroy_head_check,
947-
dsl_destroy_head_sync, &ddha, 0));
948+
dsl_destroy_head_sync, &ddha, 0, ZFS_SPACE_CHECK_NONE));
948949
}
949950

950951
/*

module/zfs/dsl_dir.c

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@
2020
*/
2121
/*
2222
* Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
23-
* Copyright (c) 2013 by Delphix. All rights reserved.
23+
* Copyright (c) 2012, 2014 by Delphix. All rights reserved.
2424
* Copyright (c) 2013 Martin Matuska. All rights reserved.
2525
* Copyright (c) 2014 Joyent, Inc. All rights reserved.
2626
* Copyright (c) 2014 Spectra Logic Corporation, All rights reserved.
@@ -665,7 +665,8 @@ dsl_dir_activate_fs_ss_limit(const char *ddname)
665665
int error;
666666

667667
error = dsl_sync_task(ddname, dsl_dir_actv_fs_ss_limit_check,
668-
dsl_dir_actv_fs_ss_limit_sync, (void *)ddname, 0);
668+
dsl_dir_actv_fs_ss_limit_sync, (void *)ddname, 0,
669+
ZFS_SPACE_CHECK_RESERVED);
669670

670671
if (error == EALREADY)
671672
error = 0;
@@ -1529,7 +1530,7 @@ dsl_dir_set_quota(const char *ddname, zprop_source_t source, uint64_t quota)
15291530
ddsqra.ddsqra_value = quota;
15301531

15311532
return (dsl_sync_task(ddname, dsl_dir_set_quota_check,
1532-
dsl_dir_set_quota_sync, &ddsqra, 0));
1533+
dsl_dir_set_quota_sync, &ddsqra, 0, ZFS_SPACE_CHECK_NONE));
15331534
}
15341535

15351536
int
@@ -1650,7 +1651,7 @@ dsl_dir_set_reservation(const char *ddname, zprop_source_t source,
16501651
ddsqra.ddsqra_value = reservation;
16511652

16521653
return (dsl_sync_task(ddname, dsl_dir_set_reservation_check,
1653-
dsl_dir_set_reservation_sync, &ddsqra, 0));
1654+
dsl_dir_set_reservation_sync, &ddsqra, 0, ZFS_SPACE_CHECK_NONE));
16541655
}
16551656

16561657
static dsl_dir_t *
@@ -1932,7 +1933,8 @@ dsl_dir_rename(const char *oldname, const char *newname)
19321933
ddra.ddra_cred = CRED();
19331934

19341935
return (dsl_sync_task(oldname,
1935-
dsl_dir_rename_check, dsl_dir_rename_sync, &ddra, 3));
1936+
dsl_dir_rename_check, dsl_dir_rename_sync, &ddra,
1937+
3, ZFS_SPACE_CHECK_RESERVED));
19361938
}
19371939

19381940
int

0 commit comments

Comments
 (0)