Skip to content

Commit

Permalink
Illumos 3897 - zfs filesystem and snapshot limits
Browse files Browse the repository at this point in the history
3897 zfs filesystem and snapshot limits
Author: Jerry Jelinek <[email protected]>
Reviewed by: Matthew Ahrens <[email protected]>
Approved by: Christopher Siden <[email protected]>

References:
  https://www.illumos.org/issues/3897
  illumos/illumos-gate@a2afb61

Porting Notes:

dsl_dataset_snapshot_check(): reduce stack usage using kmem_alloc().

Ported-by: Chris Dunlop <[email protected]>
Signed-off-by: Brian Behlendorf <[email protected]>
  • Loading branch information
jjelinek authored and behlendorf committed Apr 28, 2015
1 parent 308a451 commit 788eb90
Show file tree
Hide file tree
Showing 19 changed files with 1,021 additions and 27 deletions.
3 changes: 2 additions & 1 deletion include/sys/dmu_send.h
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@
* Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2013 by Delphix. All rights reserved.
* Copyright 2011 Nexenta Systems, Inc. All rights reserved.
* Copyright (c) 2012, Joyent, Inc. All rights reserved.
* Copyright (c) 2013, Joyent, Inc. All rights reserved.
*/

#ifndef _DMU_SEND_H
Expand Down Expand Up @@ -56,6 +56,7 @@ typedef struct dmu_recv_cookie {
zio_cksum_t drc_cksum;
uint64_t drc_newsnapobj;
void *drc_owner;
cred_t *drc_cred;
} dmu_recv_cookie_t;

int dmu_recv_begin(char *tofs, char *tosnap, struct drr_begin *drrb,
Expand Down
7 changes: 4 additions & 3 deletions include/sys/dsl_dataset.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@
/*
* Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2013 by Delphix. All rights reserved.
* Copyright (c) 2012, Joyent, Inc. All rights reserved.
* Copyright (c) 2013, Joyent, Inc. All rights reserved.
* Copyright (c) 2013 Steven Hartland. All rights reserved.
*/

Expand Down Expand Up @@ -266,7 +266,7 @@ int dsl_dataset_clone_swap_check_impl(dsl_dataset_t *clone,
void dsl_dataset_clone_swap_sync_impl(dsl_dataset_t *clone,
dsl_dataset_t *origin_head, dmu_tx_t *tx);
int dsl_dataset_snapshot_check_impl(dsl_dataset_t *ds, const char *snapname,
dmu_tx_t *tx, boolean_t recv);
dmu_tx_t *tx, boolean_t recv, uint64_t cnt, cred_t *cr);
void dsl_dataset_snapshot_sync_impl(dsl_dataset_t *ds, const char *snapname,
dmu_tx_t *tx);

Expand All @@ -276,7 +276,8 @@ void dsl_dataset_recalc_head_uniq(dsl_dataset_t *ds);
int dsl_dataset_get_snapname(dsl_dataset_t *ds);
int dsl_dataset_snap_lookup(dsl_dataset_t *ds, const char *name,
uint64_t *value);
int dsl_dataset_snap_remove(dsl_dataset_t *ds, const char *name, dmu_tx_t *tx);
int dsl_dataset_snap_remove(dsl_dataset_t *ds, const char *name, dmu_tx_t *tx,
boolean_t adj_cnt);
void dsl_dataset_set_refreservation_sync_impl(dsl_dataset_t *ds,
zprop_source_t source, uint64_t value, dmu_tx_t *tx);
void dsl_dataset_zapify(dsl_dataset_t *ds, dmu_tx_t *tx);
Expand Down
18 changes: 17 additions & 1 deletion include/sys/dsl_dir.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
/*
* Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2013 by Delphix. All rights reserved.
* Copyright (c) 2014, Joyent, Inc. All rights reserved.
*/

#ifndef _SYS_DSL_DIR_H
Expand All @@ -38,6 +39,14 @@ extern "C" {

struct dsl_dataset;

/*
* DD_FIELD_* are strings that are used in the "extensified" dsl_dir zap object.
* They should be of the format <reverse-dns>:<field>.
*/

#define DD_FIELD_FILESYSTEM_COUNT "com.joyent:filesystem_count"
#define DD_FIELD_SNAPSHOT_COUNT "com.joyent:snapshot_count"

typedef enum dd_used {
DD_USED_HEAD,
DD_USED_SNAP,
Expand Down Expand Up @@ -129,15 +138,22 @@ int dsl_dir_set_quota(const char *ddname, zprop_source_t source,
uint64_t quota);
int dsl_dir_set_reservation(const char *ddname, zprop_source_t source,
uint64_t reservation);
int dsl_dir_activate_fs_ss_limit(const char *);
int dsl_fs_ss_limit_check(dsl_dir_t *, uint64_t, zfs_prop_t, dsl_dir_t *,
cred_t *);
void dsl_fs_ss_count_adjust(dsl_dir_t *, int64_t, const char *, dmu_tx_t *);
int dsl_dir_rename(const char *oldname, const char *newname);
int dsl_dir_transfer_possible(dsl_dir_t *sdd, dsl_dir_t *tdd, uint64_t space);
int dsl_dir_transfer_possible(dsl_dir_t *sdd, dsl_dir_t *tdd,
uint64_t fs_cnt, uint64_t ss_cnt, uint64_t space, cred_t *);
boolean_t dsl_dir_is_clone(dsl_dir_t *dd);
void dsl_dir_new_refreservation(dsl_dir_t *dd, struct dsl_dataset *ds,
uint64_t reservation, cred_t *cr, dmu_tx_t *tx);
void dsl_dir_snap_cmtime_update(dsl_dir_t *dd);
timestruc_t dsl_dir_snap_cmtime(dsl_dir_t *dd);
void dsl_dir_set_reservation_sync_impl(dsl_dir_t *dd, uint64_t value,
dmu_tx_t *tx);
void dsl_dir_zapify(dsl_dir_t *dd, dmu_tx_t *tx);
boolean_t dsl_dir_is_zapified(dsl_dir_t *dd);

/* internal reserved dir name */
#define MOS_DIR_NAME "$MOS"
Expand Down
6 changes: 5 additions & 1 deletion include/sys/fs/zfs.h
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@
* Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2011, 2014 by Delphix. All rights reserved.
* Copyright 2011 Nexenta Systems, Inc. All rights reserved.
* Copyright (c) 2012, Joyent, Inc. All rights reserved.
* Copyright (c) 2013, Joyent, Inc. All rights reserved.
*/

/* Portions Copyright 2010 Robert Milkowski */
Expand Down Expand Up @@ -142,6 +142,10 @@ typedef enum {
ZFS_PROP_LOGICALUSED,
ZFS_PROP_LOGICALREFERENCED,
ZFS_PROP_INCONSISTENT, /* not exposed to the user */
ZFS_PROP_FILESYSTEM_LIMIT,
ZFS_PROP_SNAPSHOT_LIMIT,
ZFS_PROP_FILESYSTEM_COUNT,
ZFS_PROP_SNAPSHOT_COUNT,
ZFS_PROP_SNAPDEV,
ZFS_PROP_ACLTYPE,
ZFS_PROP_SELINUX_CONTEXT,
Expand Down
1 change: 1 addition & 0 deletions include/zfeature_common.h
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ typedef enum spa_feature {
SPA_FEATURE_EXTENSIBLE_DATASET,
SPA_FEATURE_EMBEDDED_DATA,
SPA_FEATURE_BOOKMARKS,
SPA_FEATURE_FS_SS_LIMIT,
SPA_FEATURES
} spa_feature_t;

Expand Down
1 change: 1 addition & 0 deletions lib/libspl/include/sys/Makefile.am
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ libspl_HEADERS = \
$(top_srcdir)/lib/libspl/include/sys/mount.h \
$(top_srcdir)/lib/libspl/include/sys/note.h \
$(top_srcdir)/lib/libspl/include/sys/param.h \
$(top_srcdir)/lib/libspl/include/sys/policy.h \
$(top_srcdir)/lib/libspl/include/sys/priv.h \
$(top_srcdir)/lib/libspl/include/sys/processor.h \
$(top_srcdir)/lib/libspl/include/sys/stack.h \
Expand Down
26 changes: 26 additions & 0 deletions lib/libspl/include/sys/policy.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
/*
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License, Version 1.0 only
* (the "License"). You may not use this file except in compliance
* with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* or http://www.opensolaris.org/os/licensing.
* See the License for the specific language governing permissions
* and limitations under the License.
*
* When distributing Covered Code, include this CDDL HEADER in each
* file and include the License file at usr/src/OPENSOLARIS.LICENSE.
* If applicable, add the following below this CDDL HEADER, with the
* fields enclosed by brackets "[]" replaced with your own identifying
* information: Portions Copyright [yyyy] [name of copyright owner]
*
* CDDL HEADER END
*/

#ifndef _LIBSYS_SYS_POLICY_H
#define _LIBSYS_SYS_POLICY_H

#endif /* _LIBSYS_SYS_POLICY_H */
29 changes: 29 additions & 0 deletions lib/libzfs/libzfs_dataset.c
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@

/*
* Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2013, Joyent, Inc. All rights reserved.
* Copyright (c) 2013 by Delphix. All rights reserved.
* Copyright (c) 2012 DEY Storage Systems, Inc. All rights reserved.
* Copyright (c) 2012 Pawel Jakub Dawidek <[email protected]>.
Expand Down Expand Up @@ -1934,6 +1935,10 @@ get_numeric_property(zfs_handle_t *zhp, zfs_prop_t prop, zprop_source_t *src,
case ZFS_PROP_REFQUOTA:
case ZFS_PROP_RESERVATION:
case ZFS_PROP_REFRESERVATION:
case ZFS_PROP_FILESYSTEM_LIMIT:
case ZFS_PROP_SNAPSHOT_LIMIT:
case ZFS_PROP_FILESYSTEM_COUNT:
case ZFS_PROP_SNAPSHOT_COUNT:
*val = getprop_uint64(zhp, prop, source);

if (*source == NULL) {
Expand Down Expand Up @@ -2342,6 +2347,30 @@ zfs_prop_get(zfs_handle_t *zhp, zfs_prop_t prop, char *propbuf, size_t proplen,
}
break;

case ZFS_PROP_FILESYSTEM_LIMIT:
case ZFS_PROP_SNAPSHOT_LIMIT:
case ZFS_PROP_FILESYSTEM_COUNT:
case ZFS_PROP_SNAPSHOT_COUNT:

if (get_numeric_property(zhp, prop, src, &source, &val) != 0)
return (-1);

/*
* If limit is UINT64_MAX, we translate this into 'none' (unless
* literal is set), and indicate that it's the default value.
* Otherwise, we print the number nicely and indicate that it's
* set locally.
*/
if (literal) {
(void) snprintf(propbuf, proplen, "%llu",
(u_longlong_t)val);
} else if (val == UINT64_MAX) {
(void) strlcpy(propbuf, "none", proplen);
} else {
zfs_nicenum(val, propbuf, proplen);
}
break;

case ZFS_PROP_REFRATIO:
case ZFS_PROP_COMPRESSRATIO:
if (get_numeric_property(zhp, prop, src, &source, &val) != 0)
Expand Down
11 changes: 11 additions & 0 deletions lib/libzfs/libzfs_util.c
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@

/*
* Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2013, Joyent, Inc. All rights reserved.
* Copyright (c) 2012 by Delphix. All rights reserved.
*/

Expand Down Expand Up @@ -1478,6 +1479,16 @@ zprop_parse_value(libzfs_handle_t *hdl, nvpair_t *elem, int prop,
"use 'none' to disable quota/refquota"));
goto error;
}

/*
* Special handling for "*_limit=none". In this case it's not
* 0 but UINT64_MAX.
*/
if ((type & ZFS_TYPE_DATASET) && isnone &&
(prop == ZFS_PROP_FILESYSTEM_LIMIT ||
prop == ZFS_PROP_SNAPSHOT_LIMIT)) {
*ivalp = UINT64_MAX;
}
break;

case PROP_TYPE_INDEX:
Expand Down
22 changes: 22 additions & 0 deletions man/man5/zpool-features.5
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
'\" te
.\" Copyright (c) 2013 by Delphix. All rights reserved.
.\" Copyright (c) 2013 by Saso Kiselkov. All rights reserved.
.\" Copyright (c) 2014, Joyent, Inc. All rights reserved.
.\" The contents of this file are subject to the terms of the Common Development
.\" and Distribution License (the "License"). You may not use this file except
.\" in compliance with the License. You can obtain a copy of the license at
Expand Down Expand Up @@ -198,6 +199,27 @@ This feature is \fBactive\fR while there are any filesystems, volumes,
or snapshots which were created after enabling this feature.
.RE

.sp
.ne 2
.na
\fB\fBfilesystem_limits\fR\fR
.ad
.RS 4n
.TS
l l .
GUID com.joyent:filesystem_limits
READ\-ONLY COMPATIBLE yes
DEPENDENCIES extensible_dataset
.TE

This feature enables filesystem and snapshot limits. These limits can be used
to control how many filesystems and/or snapshots can be created at the point in
the tree on which the limits are set.

This feature is \fBactive\fR once either of the limit properties has been
set on a dataset. Once activated the feature is never deactivated.
.RE

.sp
.ne 2
.na
Expand Down
59 changes: 58 additions & 1 deletion man/man8/zfs.8
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@
.\" Copyright (c) 2009 Sun Microsystems, Inc. All Rights Reserved.
.\" Copyright 2011 Joshua M. Clulow <[email protected]>
.\" Copyright (c) 2014 by Delphix. All rights reserved.
.\" Copyright (c) 2012, Joyent, Inc. All rights reserved.
.\" Copyright (c) 2014, Joyent, Inc. All rights reserved.
.\" Copyright 2012 Nexenta Systems, Inc. All Rights Reserved.
.\" Copyright (c) 2013 by Saso Kiselkov. All rights reserved.
.\"
Expand Down Expand Up @@ -467,6 +467,18 @@ This property is \fBon\fR if the snapshot has been marked for deferred destructi
.ne 2
.mk
.na
\fB\fBfilesystem_count\fR
.ad
.sp .6
.RS 4n
The total number of filesystems and volumes that exist under this location in the
dataset tree. This value is only available when a \fBfilesystem_limit\fR has
been set somewhere in the tree under which the dataset resides.
.RE

.sp
.ne 2
.na
\fB\fBlogicalreferenced\fR\fR
.ad
.sp .6
Expand Down Expand Up @@ -549,6 +561,18 @@ property.
.ne 2
.mk
.na
\fB\fBsnapshot_count\fR
.ad
.sp .6
.RS 4n
The total number of snapshots that exist under this location in the dataset tree.
This value is only available when a \fBsnapshot_limit\fR has been set somewhere
in the tree under which the dataset resides.
.RE

.sp
.ne 2
.na
\fB\fBtype\fR\fR
.ad
.sp .6
Expand Down Expand Up @@ -910,6 +934,21 @@ Zones are a Solaris feature and are not relevant on Linux.
.ne 2
.mk
.na
\fB\fBfilesystem_limit\fR=\fIcount\fR | \fBnone\fR\fR
.ad
.sp .6
.RS 4n
Limits the number of filesystems and volumes that can exist under this point in
the dataset tree. The limit is not enforced if the user is allowed to change
the limit. Setting a filesystem_limit on a descendent of a filesystem that
already has a filesystem_limit does not override the ancestor's filesystem_limit,
but rather imposes an additional limit. This feature must be enabled to be used
(see \fBzpool-features\fR(5)).
.RE

.sp
.ne 2
.na
\fB\fBmountpoint\fR=\fIpath\fR | \fBnone\fR | \fBlegacy\fR\fR
.ad
.sp .6
Expand Down Expand Up @@ -958,6 +997,22 @@ Quotas cannot be set on volumes, as the \fBvolsize\fR property acts as an implic
.ne 2
.mk
.na
\fB\fBsnapshot_limit\fR=\fIcount\fR | \fBnone\fR\fR
.ad
.sp .6
.RS 4n
Limits the number of snapshots that can be created on a dataset and its
descendents. Setting a snapshot_limit on a descendent of a dataset that already
has a snapshot_limit does not override the ancestor's snapshot_limit, but
rather imposes an additional limit. The limit is not enforced if the user is
allowed to change the limit. For example, this means that recursive snapshots
taken from the global zone are counted against each delegated dataset within
a zone. This feature must be enabled to be used (see \fBzpool-features\fR(5)).
.RE

.sp
.ne 2
.na
\fB\fBuserquota@\fR\fIuser\fR=\fIsize\fR | \fBnone\fR\fR
.ad
.sp .6
Expand Down Expand Up @@ -3013,6 +3068,7 @@ copies property
dedup property
devices property
exec property
filesystem_limit property
logbias property
mlslabel property
mountpoint property
Expand All @@ -3031,6 +3087,7 @@ shareiscsi property
sharenfs property
sharesmb property
snapdir property
snapshot_limit property
utf8only property
version property
volblocksize property
Expand Down
12 changes: 12 additions & 0 deletions module/zcommon/zfs_prop.c
Original file line number Diff line number Diff line change
Expand Up @@ -411,6 +411,18 @@ zfs_prop_init(void)
zprop_register_number(ZFS_PROP_REFRESERVATION, "refreservation", 0,
PROP_DEFAULT, ZFS_TYPE_FILESYSTEM | ZFS_TYPE_VOLUME,
"<size> | none", "REFRESERV");
zprop_register_number(ZFS_PROP_FILESYSTEM_LIMIT, "filesystem_limit",
UINT64_MAX, PROP_DEFAULT, ZFS_TYPE_FILESYSTEM,
"<count> | none", "FSLIMIT");
zprop_register_number(ZFS_PROP_SNAPSHOT_LIMIT, "snapshot_limit",
UINT64_MAX, PROP_DEFAULT, ZFS_TYPE_FILESYSTEM | ZFS_TYPE_VOLUME,
"<count> | none", "SSLIMIT");
zprop_register_number(ZFS_PROP_FILESYSTEM_COUNT, "filesystem_count",
UINT64_MAX, PROP_DEFAULT, ZFS_TYPE_FILESYSTEM,
"<count>", "FSCOUNT");
zprop_register_number(ZFS_PROP_SNAPSHOT_COUNT, "snapshot_count",
UINT64_MAX, PROP_DEFAULT, ZFS_TYPE_FILESYSTEM | ZFS_TYPE_VOLUME,
"<count>", "SSCOUNT");

/* inherit number properties */
zprop_register_number(ZFS_PROP_RECORDSIZE, "recordsize",
Expand Down
Loading

0 comments on commit 788eb90

Please sign in to comment.