From 59d4c71cca3bd6a1f122129ebb001089f903f182 Mon Sep 17 00:00:00 2001 From: George Wilson Date: Wed, 13 Jan 2016 14:37:39 -0800 Subject: [PATCH] Illumos 3557, 3558, 3559, 3560 3557 dumpvp_size is not updated correctly when a dump zvol's size is changed 3558 setting the volsize on a dump device does not return back ENOSPC 3559 setting a volsize larger than the space available sometimes succeeds 3560 dumpadm should be able to remove a dump device Reviewed by: Adam Leventhal Reviewed by: Matthew Ahrens Reviewed by: Christopher Siden Approved by: Albert Lee References: https://www.illumos.org/issues/3559 https://github.com/illumos/illumos-gate/commit/c61ea56 Porting notes: - Internal zvol.c changes not applied due to implementation differences. The external interface and behavior was already consistent with the latest upstream code. - Retired 2.6.28 HAVE_CHECK_DISK_SIZE_CHANGE configure check. All supported kernels (2.6.32 and newer) provide this interface. Ported-by: Brian Behlendorf Closes #4217 --- cmd/zfs/zfs_main.c | 12 +++++++++++- config/kernel-check-disk-size-change.m4 | 18 ------------------ config/kernel.m4 | 1 - lib/libzfs/libzfs_dataset.c | 22 ++++++++++++++++------ module/zfs/zvol.c | 10 ---------- 5 files changed, 27 insertions(+), 36 deletions(-) delete mode 100644 config/kernel-check-disk-size-change.m4 diff --git a/cmd/zfs/zfs_main.c b/cmd/zfs/zfs_main.c index 34bfba258..177d2da48 100644 --- a/cmd/zfs/zfs_main.c +++ b/cmd/zfs/zfs_main.c @@ -833,10 +833,12 @@ zfs_do_create(int argc, char **argv) if (type == ZFS_TYPE_VOLUME && !noreserve) { zpool_handle_t *zpool_handle; + nvlist_t *real_props = NULL; uint64_t spa_version; char *p; zfs_prop_t resv_prop; char *strval; + char msg[1024]; if ((p = strchr(argv[0], '/'))) *p = '\0'; @@ -852,7 +854,15 @@ zfs_do_create(int argc, char **argv) resv_prop = ZFS_PROP_REFRESERVATION; else resv_prop = ZFS_PROP_RESERVATION; - volsize = zvol_volsize_to_reservation(volsize, props); + + (void) snprintf(msg, sizeof (msg), + gettext("cannot create '%s'"), argv[0]); + if (props && (real_props = zfs_valid_proplist(g_zfs, type, + props, 0, NULL, msg)) == NULL) + goto error; + + volsize = zvol_volsize_to_reservation(volsize, real_props); + nvlist_free(real_props); if (nvlist_lookup_string(props, zfs_prop_to_name(resv_prop), &strval) != 0) { diff --git a/config/kernel-check-disk-size-change.m4 b/config/kernel-check-disk-size-change.m4 deleted file mode 100644 index ea5c75f39..000000000 --- a/config/kernel-check-disk-size-change.m4 +++ /dev/null @@ -1,18 +0,0 @@ -dnl # -dnl # 2.6.28 API change -dnl # Added check_disk_size_change() helper function. -dnl # -AC_DEFUN([ZFS_AC_KERNEL_CHECK_DISK_SIZE_CHANGE], - [AC_MSG_CHECKING([whether check_disk_size_change() is available]) - ZFS_LINUX_TRY_COMPILE_SYMBOL([ - #include - ], [ - check_disk_size_change(NULL, NULL); - ], [check_disk_size_change], [fs/block_dev.c], [ - AC_MSG_RESULT(yes) - AC_DEFINE(HAVE_CHECK_DISK_SIZE_CHANGE, 1, - [check_disk_size_change() is available]) - ], [ - AC_MSG_RESULT(no) - ]) -]) diff --git a/config/kernel.m4 b/config/kernel.m4 index 31ba79f04..16fb017fe 100644 --- a/config/kernel.m4 +++ b/config/kernel.m4 @@ -72,7 +72,6 @@ AC_DEFUN([ZFS_AC_CONFIG_KERNEL], [ ZFS_AC_KERNEL_D_SET_D_OP ZFS_AC_KERNEL_D_REVALIDATE_NAMEIDATA ZFS_AC_KERNEL_CONST_DENTRY_OPERATIONS - ZFS_AC_KERNEL_CHECK_DISK_SIZE_CHANGE ZFS_AC_KERNEL_TRUNCATE_SETSIZE ZFS_AC_KERNEL_6ARGS_SECURITY_INODE_INIT_SECURITY ZFS_AC_KERNEL_CALLBACK_SECURITY_INODE_INIT_SECURITY diff --git a/lib/libzfs/libzfs_dataset.c b/lib/libzfs/libzfs_dataset.c index 2a85b31c9..7bcfd6a81 100644 --- a/lib/libzfs/libzfs_dataset.c +++ b/lib/libzfs/libzfs_dataset.c @@ -1379,6 +1379,7 @@ zfs_add_synthetic_resv(zfs_handle_t *zhp, nvlist_t *nvl) uint64_t old_reservation; uint64_t new_reservation; zfs_prop_t resv_prop; + nvlist_t *props; /* * If this is an existing volume, and someone is setting the volsize, @@ -1388,16 +1389,25 @@ zfs_add_synthetic_resv(zfs_handle_t *zhp, nvlist_t *nvl) if (zfs_which_resv_prop(zhp, &resv_prop) < 0) return (-1); old_reservation = zfs_prop_get_int(zhp, resv_prop); - if ((zvol_volsize_to_reservation(old_volsize, zhp->zfs_props) != - old_reservation) || nvlist_lookup_uint64(nvl, - zfs_prop_to_name(resv_prop), &new_reservation) != ENOENT) { + + props = fnvlist_alloc(); + fnvlist_add_uint64(props, zfs_prop_to_name(ZFS_PROP_VOLBLOCKSIZE), + zfs_prop_get_int(zhp, ZFS_PROP_VOLBLOCKSIZE)); + + if ((zvol_volsize_to_reservation(old_volsize, props) != + old_reservation) || nvlist_exists(nvl, + zfs_prop_to_name(resv_prop))) { + fnvlist_free(props); return (0); } if (nvlist_lookup_uint64(nvl, zfs_prop_to_name(ZFS_PROP_VOLSIZE), - &new_volsize) != 0) + &new_volsize) != 0) { + fnvlist_free(props); return (-1); - new_reservation = zvol_volsize_to_reservation(new_volsize, - zhp->zfs_props); + } + new_reservation = zvol_volsize_to_reservation(new_volsize, props); + fnvlist_free(props); + if (nvlist_add_uint64(nvl, zfs_prop_to_name(resv_prop), new_reservation) != 0) { (void) no_memory(zhp->zfs_hdl); diff --git a/module/zfs/zvol.c b/module/zfs/zvol.c index 1e27d81d6..9b7ab542d 100644 --- a/module/zfs/zvol.c +++ b/module/zfs/zvol.c @@ -238,19 +238,9 @@ zvol_size_changed(zvol_state_t *zv, uint64_t volsize) bdev = bdget_disk(zv->zv_disk, 0); if (bdev == NULL) return; -/* - * 2.6.28 API change - * Added check_disk_size_change() helper function. - */ -#ifdef HAVE_CHECK_DISK_SIZE_CHANGE set_capacity(zv->zv_disk, volsize >> 9); zv->zv_volsize = volsize; check_disk_size_change(zv->zv_disk, bdev); -#else - zv->zv_volsize = volsize; - zv->zv_changed = 1; - (void) check_disk_change(bdev); -#endif /* HAVE_CHECK_DISK_SIZE_CHANGE */ bdput(bdev); } -- 2.40.0