diff options
author | mm <mm@FreeBSD.org> | 2012-06-11 11:35:22 +0000 |
---|---|---|
committer | mm <mm@FreeBSD.org> | 2012-06-11 11:35:22 +0000 |
commit | cc61ab2f133566dca51970d44cc49a4355039b5d (patch) | |
tree | a0efb9ad759cc8c8f8ec6f2cbabe6b3305a334e9 /sys/boot/zfs | |
parent | 2cecdd81d885af2868172221b5068c523eade78c (diff) | |
download | FreeBSD-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.c | 67 |
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)) { |