]> git.proxmox.com Git - mirror_zfs.git/blobdiff - module/zfs/zfs_ioctl.c
zfs initialize performance enhancements
[mirror_zfs.git] / module / zfs / zfs_ioctl.c
index 3c36502d8599e321830b0591c9c919f6ca198d82..0dfa016845a33a4cf49d99a0ad70eb56def705c2 100644 (file)
@@ -3846,73 +3846,68 @@ zfs_ioc_destroy(zfs_cmd_t *zc)
 
 /*
  * innvl: {
- *     vdevs: {
- *         guid 1, guid 2, ...
+ *     "initialize_command" -> POOL_INITIALIZE_{CANCEL|DO|SUSPEND} (uint64)
+ *     "initialize_vdevs": { -> guids to initialize (nvlist)
+ *         "vdev_path_1": vdev_guid_1, (uint64),
+ *         "vdev_path_2": vdev_guid_2, (uint64),
+ *         ...
  *     },
- *     func: POOL_INITIALIZE_{CANCEL|DO|SUSPEND}
  * }
  *
  * outnvl: {
- *     [func: EINVAL (if provided command type didn't make sense)],
- *     [vdevs: {
- *         guid1: errno, (see function body for possible errnos)
+ *     "initialize_vdevs": { -> initialization errors (nvlist)
+ *         "vdev_path_1": errno, see function body for possible errnos (uint64)
+ *         "vdev_path_2": errno, ... (uint64)
  *         ...
- *     }]
+ *     }
  * }
  *
+ * EINVAL is returned for an unknown commands or if any of the provided vdev
+ * guids have be specified with a type other than uint64.
  */
 static const zfs_ioc_key_t zfs_keys_pool_initialize[] = {
-       {ZPOOL_INITIALIZE_COMMAND,      DATA_TYPE_UINT64,       0},
+       {ZPOOL_INITIALIZE_COMMAND,      DATA_TYPE_UINT64,       0},
        {ZPOOL_INITIALIZE_VDEVS,        DATA_TYPE_NVLIST,       0}
 };
 
 static int
 zfs_ioc_pool_initialize(const char *poolname, nvlist_t *innvl, nvlist_t *outnvl)
 {
-       spa_t *spa;
-       int error;
-
-       error = spa_open(poolname, &spa, FTAG);
-       if (error != 0)
-               return (error);
-
        uint64_t cmd_type;
        if (nvlist_lookup_uint64(innvl, ZPOOL_INITIALIZE_COMMAND,
            &cmd_type) != 0) {
-               spa_close(spa, FTAG);
                return (SET_ERROR(EINVAL));
        }
+
        if (!(cmd_type == POOL_INITIALIZE_CANCEL ||
            cmd_type == POOL_INITIALIZE_DO ||
            cmd_type == POOL_INITIALIZE_SUSPEND)) {
-               spa_close(spa, FTAG);
                return (SET_ERROR(EINVAL));
        }
 
        nvlist_t *vdev_guids;
        if (nvlist_lookup_nvlist(innvl, ZPOOL_INITIALIZE_VDEVS,
            &vdev_guids) != 0) {
-               spa_close(spa, FTAG);
                return (SET_ERROR(EINVAL));
        }
 
-       nvlist_t *vdev_errlist = fnvlist_alloc();
-       int total_errors = 0;
-
        for (nvpair_t *pair = nvlist_next_nvpair(vdev_guids, NULL);
            pair != NULL; pair = nvlist_next_nvpair(vdev_guids, pair)) {
-               uint64_t vdev_guid = fnvpair_value_uint64(pair);
-
-               error = spa_vdev_initialize(spa, vdev_guid, cmd_type);
-               if (error != 0) {
-                       char guid_as_str[MAXNAMELEN];
-
-                       (void) snprintf(guid_as_str, sizeof (guid_as_str),
-                           "%llu", (unsigned long long)vdev_guid);
-                       fnvlist_add_int64(vdev_errlist, guid_as_str, error);
-                       total_errors++;
+               uint64_t vdev_guid;
+               if (nvpair_value_uint64(pair, &vdev_guid) != 0) {
+                       return (SET_ERROR(EINVAL));
                }
        }
+
+       spa_t *spa;
+       int error = spa_open(poolname, &spa, FTAG);
+       if (error != 0)
+               return (error);
+
+       nvlist_t *vdev_errlist = fnvlist_alloc();
+       int total_errors = spa_vdev_initialize(spa, vdev_guids, cmd_type,
+           vdev_errlist);
+
        if (fnvlist_size(vdev_errlist) > 0) {
                fnvlist_add_nvlist(outnvl, ZPOOL_INITIALIZE_VDEVS,
                    vdev_errlist);