summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/sys/fs/zfs.h1
-rw-r--r--include/sys/zfs_ioctl.h6
-rw-r--r--include/sys/zvol.h1
-rw-r--r--lib/libzfs/libzfs_dataset.c8
-rw-r--r--man/man8/zfs.811
-rw-r--r--module/zcommon/zfs_prop.c9
-rw-r--r--module/zfs/zfs_ioctl.c3
-rw-r--r--module/zfs/zvol.c62
-rwxr-xr-xscripts/zconfig.sh5
9 files changed, 103 insertions, 3 deletions
diff --git a/include/sys/fs/zfs.h b/include/sys/fs/zfs.h
index 137dd39e6..8c949e767 100644
--- a/include/sys/fs/zfs.h
+++ b/include/sys/fs/zfs.h
@@ -128,6 +128,7 @@ typedef enum {
ZFS_PROP_REFRATIO,
ZFS_PROP_WRITTEN,
ZFS_PROP_CLONES,
+ ZFS_PROP_SNAPDEV,
ZFS_NUM_PROPS
} zfs_prop_t;
diff --git a/include/sys/zfs_ioctl.h b/include/sys/zfs_ioctl.h
index 4e5c5fba2..740d8eda4 100644
--- a/include/sys/zfs_ioctl.h
+++ b/include/sys/zfs_ioctl.h
@@ -47,6 +47,12 @@ extern "C" {
#define ZFS_SNAPDIR_VISIBLE 1
/*
+ * Property values for snapdev
+ */
+#define ZFS_SNAPDEV_HIDDEN 0
+#define ZFS_SNAPDEV_VISIBLE 1
+
+/*
* Field manipulation macros for the drr_versioninfo field of the
* send stream header.
*/
diff --git a/include/sys/zvol.h b/include/sys/zvol.h
index 185d64523..c05f81a5f 100644
--- a/include/sys/zvol.h
+++ b/include/sys/zvol.h
@@ -44,6 +44,7 @@ extern int zvol_remove_minor(const char *);
extern void zvol_remove_minors(const char *);
extern int zvol_set_volsize(const char *, uint64_t);
extern int zvol_set_volblocksize(const char *, uint64_t);
+extern int zvol_set_snapdev(const char *, uint64_t);
extern int zvol_init(void);
extern void zvol_fini(void);
diff --git a/lib/libzfs/libzfs_dataset.c b/lib/libzfs/libzfs_dataset.c
index 73d45882a..d4691dd2a 100644
--- a/lib/libzfs/libzfs_dataset.c
+++ b/lib/libzfs/libzfs_dataset.c
@@ -4016,6 +4016,14 @@ zvol_create_link_common(libzfs_handle_t *hdl, const char *dataset, int ifexists)
*/
return (0);
+ case ENODEV:
+ /*
+ * snapdev set to hidden :
+ * device creation was not permitted (see zvol.c)
+ * ignore error quietly
+ */
+ return (0);
+
case ENOENT:
/*
* Dataset does not exist in the kernel. If we
diff --git a/man/man8/zfs.8 b/man/man8/zfs.8
index edfd5e797..6f648f7ae 100644
--- a/man/man8/zfs.8
+++ b/man/man8/zfs.8
@@ -1085,6 +1085,17 @@ Provide a hint to ZFS about handling of synchronous requests in this dataset. If
.ne 2
.mk
.na
+\fB\fBsnapdev\fR=\fBhidden\fR | \fBvisible\fR\fR
+.ad
+.sp .6
+.RS 4n
+Controls whether the snapshots devices of zvol's are hidden or visible. The default value is \fBhidden\fR.
+.RE
+
+.sp
+.ne 2
+.mk
+.na
\fB\fBsnapdir\fR=\fBhidden\fR | \fBvisible\fR\fR
.ad
.sp .6
diff --git a/module/zcommon/zfs_prop.c b/module/zcommon/zfs_prop.c
index 6aa38382b..b27e4f36f 100644
--- a/module/zcommon/zfs_prop.c
+++ b/module/zcommon/zfs_prop.c
@@ -106,6 +106,12 @@ zfs_prop_init(void)
{ NULL }
};
+ static zprop_index_t snapdev_table[] = {
+ { "hidden", ZFS_SNAPDEV_HIDDEN },
+ { "visible", ZFS_SNAPDEV_VISIBLE },
+ { NULL }
+ };
+
static zprop_index_t acl_inherit_table[] = {
{ "discard", ZFS_ACL_DISCARD },
{ "noallow", ZFS_ACL_NOALLOW },
@@ -217,6 +223,9 @@ zfs_prop_init(void)
zprop_register_index(ZFS_PROP_SNAPDIR, "snapdir", ZFS_SNAPDIR_HIDDEN,
PROP_INHERIT, ZFS_TYPE_FILESYSTEM,
"hidden | visible", "SNAPDIR", snapdir_table);
+ zprop_register_index(ZFS_PROP_SNAPDEV, "snapdev", ZFS_SNAPDEV_HIDDEN,
+ PROP_INHERIT, ZFS_TYPE_FILESYSTEM | ZFS_TYPE_VOLUME,
+ "hidden | visible", "SNAPDEV", snapdev_table);
zprop_register_index(ZFS_PROP_ACLINHERIT, "aclinherit",
ZFS_ACL_RESTRICTED, PROP_INHERIT, ZFS_TYPE_FILESYSTEM,
"discard | noallow | restricted | passthrough | passthrough-x",
diff --git a/module/zfs/zfs_ioctl.c b/module/zfs/zfs_ioctl.c
index e804cce08..5560b2548 100644
--- a/module/zfs/zfs_ioctl.c
+++ b/module/zfs/zfs_ioctl.c
@@ -2184,6 +2184,9 @@ zfs_prop_set_special(const char *dsname, zprop_source_t source,
case ZFS_PROP_VOLSIZE:
err = zvol_set_volsize(dsname, intval);
break;
+ case ZFS_PROP_SNAPDEV:
+ err = zvol_set_snapdev(dsname, intval);
+ break;
case ZFS_PROP_VERSION:
{
zfs_sb_t *zsb;
diff --git a/module/zfs/zvol.c b/module/zfs/zvol.c
index b0d59fe0c..b41eeb202 100644
--- a/module/zfs/zvol.c
+++ b/module/zfs/zvol.c
@@ -1288,7 +1288,28 @@ zvol_free(zvol_state_t *zv)
}
static int
-__zvol_create_minor(const char *name)
+__zvol_snapdev_hidden(const char *name)
+{
+ uint64_t snapdev;
+ char *parent;
+ char *atp;
+ int error = 0;
+
+ parent = kmem_alloc(MAXPATHLEN, KM_SLEEP);
+ (void) strlcpy(parent, name, MAXPATHLEN);
+
+ if ((atp = strrchr(parent, '@')) != NULL) {
+ *atp = '\0';
+ error = dsl_prop_get_integer(parent, "snapdev", &snapdev, NULL);
+ if ((error == 0) && (snapdev == ZFS_SNAPDEV_HIDDEN))
+ error = ENODEV;
+ }
+ kmem_free(parent, MAXPATHLEN);
+ return (error);
+}
+
+static int
+__zvol_create_minor(const char *name, boolean_t ignore_snapdev)
{
zvol_state_t *zv;
objset_t *os;
@@ -1305,6 +1326,12 @@ __zvol_create_minor(const char *name)
goto out;
}
+ if (ignore_snapdev == B_FALSE) {
+ error = __zvol_snapdev_hidden(name);
+ if (error)
+ goto out;
+ }
+
doi = kmem_alloc(sizeof(dmu_object_info_t), KM_SLEEP);
error = dmu_objset_own(name, DMU_OST_ZVOL, B_TRUE, zvol_tag, &os);
@@ -1386,7 +1413,7 @@ zvol_create_minor(const char *name)
int error;
mutex_enter(&zvol_state_lock);
- error = __zvol_create_minor(name);
+ error = __zvol_create_minor(name, B_FALSE);
mutex_exit(&zvol_state_lock);
return (error);
@@ -1434,7 +1461,7 @@ zvol_create_minors_cb(spa_t *spa, uint64_t dsobj,
if (strchr(dsname, '/') == NULL)
return 0;
- (void) __zvol_create_minor(dsname);
+ (void) __zvol_create_minor(dsname, B_FALSE);
return (0);
}
@@ -1502,6 +1529,35 @@ zvol_remove_minors(const char *pool)
kmem_free(str, MAXNAMELEN);
}
+static int
+snapdev_snapshot_changed_cb(const char *dsname, void *arg) {
+ uint64_t snapdev = *(uint64_t *) arg;
+
+ if (strchr(dsname, '@') == NULL)
+ return 0;
+
+ switch (snapdev) {
+ case ZFS_SNAPDEV_VISIBLE:
+ mutex_enter(&zvol_state_lock);
+ (void) __zvol_create_minor(dsname, B_TRUE);
+ mutex_exit(&zvol_state_lock);
+ break;
+ case ZFS_SNAPDEV_HIDDEN:
+ (void) zvol_remove_minor(dsname);
+ break;
+ }
+ return 0;
+}
+
+int
+zvol_set_snapdev(const char *dsname, uint64_t snapdev) {
+ (void) dmu_objset_find((char *) dsname, snapdev_snapshot_changed_cb,
+ &snapdev, DS_FIND_SNAPSHOTS | DS_FIND_CHILDREN);
+ /* caller should continue to modify snapdev property */
+ return (-1);
+}
+
+
int
zvol_init(void)
{
diff --git a/scripts/zconfig.sh b/scripts/zconfig.sh
index 83a6fac22..141348c03 100755
--- a/scripts/zconfig.sh
+++ b/scripts/zconfig.sh
@@ -192,6 +192,7 @@ test_3() {
${ZFS_SH} zfs="spa_config_path=${TMP_CACHE}" || fail 1
${ZPOOL_CREATE_SH} -p ${POOL_NAME} -c lo-raidz2 || fail 2
${ZFS} create -V 100M ${FULL_ZVOL_NAME} || fail 3
+ ${ZFS} set snapdev=visible ${FULL_ZVOL_NAME} || fail 3
label /dev/zvol/${FULL_ZVOL_NAME} msdos || fail 4
partition /dev/zvol/${FULL_ZVOL_NAME} primary 1% 50% || fail 4
partition /dev/zvol/${FULL_ZVOL_NAME} primary 51% -1 || fail 4
@@ -245,6 +246,7 @@ test_4() {
${ZFS_SH} zfs="spa_config_path=${TMP_CACHE}" || fail 1
${ZPOOL_CREATE_SH} -p ${POOL_NAME} -c lo-raidz2 || fail 2
${ZFS} create -V 100M ${FULL_ZVOL_NAME} || fail 3
+ ${ZFS} set snapdev=visible ${FULL_ZVOL_NAME} || fail 3
label /dev/zvol/${FULL_ZVOL_NAME} msdos || fail 4
partition /dev/zvol/${FULL_ZVOL_NAME} primary 1% 50% || fail 4
partition /dev/zvol/${FULL_ZVOL_NAME} primary 51% -1 || fail 4
@@ -335,6 +337,7 @@ test_6() {
${ZFS_SH} zfs="spa_config_path=${TMP_CACHE}" || fail 1
${ZPOOL_CREATE_SH} -p ${POOL_NAME} -c lo-raid0 || fail 2
${ZFS} create -V 800M ${FULL_ZVOL_NAME} || fail 3
+ ${ZFS} set snapdev=visible ${FULL_ZVOL_NAME} || fail 3
label /dev/zvol/${FULL_ZVOL_NAME} msdos || fail 4
partition /dev/zvol/${FULL_ZVOL_NAME} primary 1 -1 || fail 4
format /dev/zvol/${FULL_ZVOL_NAME}-part1 ext2 || fail 5
@@ -394,6 +397,7 @@ test_7() {
${ZFS_SH} zfs="spa_config_path=${TMP_CACHE}" || fail 1
${ZPOOL_CREATE_SH} -p ${POOL_NAME} -c lo-raidz2 || fail 2
${ZFS} create -V 300M ${FULL_ZVOL_NAME} || fail 3
+ ${ZFS} set snapdev=visible ${FULL_ZVOL_NAME} || fail 3
label /dev/zvol/${FULL_ZVOL_NAME} msdos || fail 4
partition /dev/zvol/${FULL_ZVOL_NAME} primary 1 -1 || fail 4
format /dev/zvol/${FULL_ZVOL_NAME}-part1 ext2 || fail 5
@@ -481,6 +485,7 @@ test_8() {
${ZPOOL_CREATE_SH} -p ${POOL_NAME1} -c lo-raidz2 || fail 2
${ZPOOL_CREATE_SH} -p ${POOL_NAME2} -c lo-raidz2 || fail 2
${ZFS} create -V 300M ${FULL_ZVOL_NAME1} || fail 3
+ ${ZFS} set snapdev=visible ${FULL_ZVOL_NAME1} || fail 3
label /dev/zvol/${FULL_ZVOL_NAME1} msdos || fail 4
partition /dev/zvol/${FULL_ZVOL_NAME1} primary 1 -1 || fail 4
format /dev/zvol/${FULL_ZVOL_NAME1}-part1 ext2 || fail 5