summaryrefslogtreecommitdiffstats
path: root/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/vdev_disk.c
diff options
context:
space:
mode:
authormm <mm@FreeBSD.org>2012-05-27 16:00:00 +0000
committermm <mm@FreeBSD.org>2012-05-27 16:00:00 +0000
commit38ef930079cbb1df5de9df3c1064426dba3976b1 (patch)
tree30fa7a955d657db9e029a43bcefda627cc7a28c8 /sys/cddl/contrib/opensolaris/uts/common/fs/zfs/vdev_disk.c
parenta672aabea920d34e84bd86ff013aa294bf6a5f7b (diff)
downloadFreeBSD-src-38ef930079cbb1df5de9df3c1064426dba3976b1.zip
FreeBSD-src-38ef930079cbb1df5de9df3c1064426dba3976b1.tar.gz
Import illumos changeset 13570:3411fd5f1589
1948 zpool list should show more detailed pool information Display per-vdev information with "zpool list -v". The added expandsize property has currently no value on FreeBSD. This changeset allows adding expansion support to individual vdevs in the future. References: https://www.illumos.org/issues/1948 Obtained from: illumos (issue #1948) MFC after: 2 weeks
Diffstat (limited to 'sys/cddl/contrib/opensolaris/uts/common/fs/zfs/vdev_disk.c')
-rw-r--r--sys/cddl/contrib/opensolaris/uts/common/fs/zfs/vdev_disk.c64
1 files changed, 53 insertions, 11 deletions
diff --git a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/vdev_disk.c b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/vdev_disk.c
index d741773..759f0f8 100644
--- a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/vdev_disk.c
+++ b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/vdev_disk.c
@@ -20,6 +20,7 @@
*/
/*
* Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012 by Delphix. All rights reserved.
*/
#include <sys/zfs_context.h>
@@ -30,6 +31,7 @@
#include <sys/fs/zfs.h>
#include <sys/zio.h>
#include <sys/sunldi.h>
+#include <sys/efi_partition.h>
#include <sys/fm/fs/zfs.h>
/*
@@ -102,8 +104,39 @@ vdev_disk_rele(vdev_t *vd)
}
}
+static uint64_t
+vdev_disk_get_space(vdev_t *vd, uint64_t capacity, uint_t blksz)
+{
+ ASSERT(vd->vdev_wholedisk);
+
+ vdev_disk_t *dvd = vd->vdev_tsd;
+ dk_efi_t dk_ioc;
+ efi_gpt_t *efi;
+ uint64_t avail_space = 0;
+ int efisize = EFI_LABEL_SIZE * 2;
+
+ dk_ioc.dki_data = kmem_alloc(efisize, KM_SLEEP);
+ dk_ioc.dki_lba = 1;
+ dk_ioc.dki_length = efisize;
+ dk_ioc.dki_data_64 = (uint64_t)(uintptr_t)dk_ioc.dki_data;
+ efi = dk_ioc.dki_data;
+
+ if (ldi_ioctl(dvd->vd_lh, DKIOCGETEFI, (intptr_t)&dk_ioc,
+ FKIOCTL, kcred, NULL) == 0) {
+ uint64_t efi_altern_lba = LE_64(efi->efi_gpt_AlternateLBA);
+
+ zfs_dbgmsg("vdev %s, capacity %llu, altern lba %llu",
+ vd->vdev_path, capacity, efi_altern_lba);
+ if (capacity > efi_altern_lba)
+ avail_space = (capacity - efi_altern_lba) * blksz;
+ }
+ kmem_free(dk_ioc.dki_data, efisize);
+ return (avail_space);
+}
+
static int
-vdev_disk_open(vdev_t *vd, uint64_t *psize, uint64_t *ashift)
+vdev_disk_open(vdev_t *vd, uint64_t *psize, uint64_t *max_psize,
+ uint64_t *ashift)
{
spa_t *spa = vd->vdev_spa;
vdev_disk_t *dvd;
@@ -274,16 +307,6 @@ skip_open:
}
/*
- * If we own the whole disk, try to enable disk write caching.
- * We ignore errors because it's OK if we can't do it.
- */
- if (vd->vdev_wholedisk == 1) {
- int wce = 1;
- (void) ldi_ioctl(dvd->vd_lh, DKIOCSETWCE, (intptr_t)&wce,
- FKIOCTL, kcred, NULL);
- }
-
- /*
* Determine the device's minimum transfer size.
* If the ioctl isn't supported, assume DEV_BSIZE.
*/
@@ -293,6 +316,25 @@ skip_open:
*ashift = highbit(MAX(dkmext.dki_pbsize, SPA_MINBLOCKSIZE)) - 1;
+ if (vd->vdev_wholedisk == 1) {
+ uint64_t capacity = dkmext.dki_capacity - 1;
+ uint64_t blksz = dkmext.dki_lbsize;
+ int wce = 1;
+
+ /*
+ * If we own the whole disk, try to enable disk write caching.
+ * We ignore errors because it's OK if we can't do it.
+ */
+ (void) ldi_ioctl(dvd->vd_lh, DKIOCSETWCE, (intptr_t)&wce,
+ FKIOCTL, kcred, NULL);
+
+ *max_psize = *psize + vdev_disk_get_space(vd, capacity, blksz);
+ zfs_dbgmsg("capacity change: vdev %s, psize %llu, "
+ "max_psize %llu", vd->vdev_path, *psize, *max_psize);
+ } else {
+ *max_psize = *psize;
+ }
+
/*
* Clear the nowritecache bit, so that on a vdev_reopen() we will
* try again.
OpenPOWER on IntegriCloud