diff options
-rw-r--r-- | include/sys/fs/zfs.h | 1 | ||||
-rw-r--r-- | include/sys/zfs_ioctl.h | 6 | ||||
-rw-r--r-- | include/sys/zvol.h | 1 | ||||
-rw-r--r-- | lib/libzfs/libzfs_dataset.c | 8 | ||||
-rw-r--r-- | man/man8/zfs.8 | 11 | ||||
-rw-r--r-- | module/zcommon/zfs_prop.c | 9 | ||||
-rw-r--r-- | module/zfs/zfs_ioctl.c | 3 | ||||
-rw-r--r-- | module/zfs/zvol.c | 62 | ||||
-rwxr-xr-x | scripts/zconfig.sh | 5 |
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 |