summaryrefslogtreecommitdiffstats
path: root/sys/boot/zfs
diff options
context:
space:
mode:
authormm <mm@FreeBSD.org>2012-06-11 11:35:22 +0000
committermm <mm@FreeBSD.org>2012-06-11 11:35:22 +0000
commitcc61ab2f133566dca51970d44cc49a4355039b5d (patch)
treea0efb9ad759cc8c8f8ec6f2cbabe6b3305a334e9 /sys/boot/zfs
parent2cecdd81d885af2868172221b5068c523eade78c (diff)
downloadFreeBSD-src-cc61ab2f133566dca51970d44cc49a4355039b5d.zip
FreeBSD-src-cc61ab2f133566dca51970d44cc49a4355039b5d.tar.gz
Introduce "feature flags" for ZFS pools (bump SPA version to 5000).
Add first feature "com.delphix:async_destroy" (asynchronous destroy of ZFS datasets). Implement features support in ZFS boot code. Illumos revisions merged: 13700:2889e2596bd6 13701:1949b688d5fb 2619 asynchronous destruction of ZFS file systems 2747 SPA versioning with zfs feature flags References: https://www.illumos.org/issues/2619 https://www.illumos.org/issues/2747 Obtained from: illumos (issue #2619, #2747) MFC after: 1 month
Diffstat (limited to 'sys/boot/zfs')
-rw-r--r--sys/boot/zfs/zfsimpl.c67
1 files changed, 66 insertions, 1 deletions
diff --git a/sys/boot/zfs/zfsimpl.c b/sys/boot/zfs/zfsimpl.c
index c37d7a5..a770e01 100644
--- a/sys/boot/zfs/zfsimpl.c
+++ b/sys/boot/zfs/zfsimpl.c
@@ -49,6 +49,13 @@ struct zfsmount {
*/
static vdev_list_t zfs_vdevs;
+ /*
+ * List of ZFS features supported for read
+ */
+static const char *features_for_read[] = {
+ NULL
+};
+
/*
* List of all pools, chained through spa_link.
*/
@@ -198,6 +205,57 @@ nvlist_find(const unsigned char *nvlist, const char *name, int type,
return (EIO);
}
+static int
+nvlist_check_features_for_read(const unsigned char *nvlist)
+{
+ const unsigned char *p, *pair;
+ int junk;
+ int encoded_size, decoded_size;
+ int rc;
+
+ rc = 0;
+
+ p = nvlist;
+ xdr_int(&p, &junk);
+ xdr_int(&p, &junk);
+
+ pair = p;
+ xdr_int(&p, &encoded_size);
+ xdr_int(&p, &decoded_size);
+ while (encoded_size && decoded_size) {
+ int namelen, pairtype;
+ const char *pairname;
+ int i, found;
+
+ found = 0;
+
+ xdr_int(&p, &namelen);
+ pairname = (const char*) p;
+ p += roundup(namelen, 4);
+ xdr_int(&p, &pairtype);
+
+ for (i = 0; features_for_read[i] != NULL; i++) {
+ if (!memcmp(pairname, features_for_read[i], namelen)) {
+ found = 1;
+ break;
+ }
+ }
+
+ if (!found) {
+ printf("ZFS: unsupported feature: %s\n", pairname);
+ rc = EIO;
+ }
+
+ p = pair + encoded_size;
+
+ pair = p;
+ xdr_int(&p, &encoded_size);
+ xdr_int(&p, &decoded_size);
+ }
+
+ return (rc);
+}
+
/*
* Return the next nvlist in an nvlist array.
*/
@@ -788,6 +846,7 @@ vdev_probe(vdev_phys_read_t *read, void *read_priv, spa_t **spap)
uint64_t is_log;
const char *pool_name;
const unsigned char *vdevs;
+ const unsigned char *features;
int i, rc, is_newer;
char *upbuf;
const struct uberblock *up;
@@ -822,12 +881,18 @@ vdev_probe(vdev_phys_read_t *read, void *read_priv, spa_t **spap)
return (EIO);
}
- if (val > SPA_VERSION) {
+ if (!SPA_VERSION_IS_SUPPORTED(val)) {
printf("ZFS: unsupported ZFS version %u (should be %u)\n",
(unsigned) val, (unsigned) SPA_VERSION);
return (EIO);
}
+ /* Check ZFS features for read */
+ rc = nvlist_find(nvlist, ZPOOL_CONFIG_FEATURES_FOR_READ,
+ DATA_TYPE_NVLIST, 0, &features);
+ if (nvlist_check_features_for_read(features) != 0)
+ return (EIO);
+
if (nvlist_find(nvlist,
ZPOOL_CONFIG_POOL_STATE,
DATA_TYPE_UINT64, 0, &val)) {
OpenPOWER on IntegriCloud