Print this page
5269 zfs: zpool import slow
While importing a pool all objsets are enumerated twice, once to check
the zil log chains and once to claim them. On pools with many datasets
this process might take a substantial amount of time.
Speed up the process by parallelizing it utilizing a taskq. The number
of parallel tasks is limited to 4 times the number of leaf vdevs.


 155 
 156         return (NULL);
 157 }
 158 
 159 vdev_t *
 160 vdev_lookup_by_guid(vdev_t *vd, uint64_t guid)
 161 {
 162         vdev_t *mvd;
 163 
 164         if (vd->vdev_guid == guid)
 165                 return (vd);
 166 
 167         for (int c = 0; c < vd->vdev_children; c++)
 168                 if ((mvd = vdev_lookup_by_guid(vd->vdev_child[c], guid)) !=
 169                     NULL)
 170                         return (mvd);
 171 
 172         return (NULL);
 173 }
 174 





















 175 void
 176 vdev_add_child(vdev_t *pvd, vdev_t *cvd)
 177 {
 178         size_t oldsize, newsize;
 179         uint64_t id = cvd->vdev_id;
 180         vdev_t **newchild;
 181 
 182         ASSERT(spa_config_held(cvd->vdev_spa, SCL_ALL, RW_WRITER) == SCL_ALL);
 183         ASSERT(cvd->vdev_parent == NULL);
 184 
 185         cvd->vdev_parent = pvd;
 186 
 187         if (pvd == NULL)
 188                 return;
 189 
 190         ASSERT(id >= pvd->vdev_children || pvd->vdev_child[id] == NULL);
 191 
 192         oldsize = pvd->vdev_children * sizeof (vdev_t *);
 193         pvd->vdev_children = MAX(pvd->vdev_children, id + 1);
 194         newsize = pvd->vdev_children * sizeof (vdev_t *);




 155 
 156         return (NULL);
 157 }
 158 
 159 vdev_t *
 160 vdev_lookup_by_guid(vdev_t *vd, uint64_t guid)
 161 {
 162         vdev_t *mvd;
 163 
 164         if (vd->vdev_guid == guid)
 165                 return (vd);
 166 
 167         for (int c = 0; c < vd->vdev_children; c++)
 168                 if ((mvd = vdev_lookup_by_guid(vd->vdev_child[c], guid)) !=
 169                     NULL)
 170                         return (mvd);
 171 
 172         return (NULL);
 173 }
 174 
 175 static int
 176 vdev_count_leaves_impl(vdev_t *vd)
 177 {
 178         vdev_t *mvd;
 179         int n = 0;
 180 
 181         if (vd->vdev_children == 0)
 182                 return (1);
 183 
 184         for (int c = 0; c < vd->vdev_children; c++)
 185                 n += vdev_count_leaves_impl(vd->vdev_child[c]);
 186 
 187         return (n);
 188 }
 189 
 190 int
 191 vdev_count_leaves(spa_t *spa)
 192 {
 193         return (vdev_count_leaves_impl(spa->spa_root_vdev));
 194 }
 195 
 196 void
 197 vdev_add_child(vdev_t *pvd, vdev_t *cvd)
 198 {
 199         size_t oldsize, newsize;
 200         uint64_t id = cvd->vdev_id;
 201         vdev_t **newchild;
 202 
 203         ASSERT(spa_config_held(cvd->vdev_spa, SCL_ALL, RW_WRITER) == SCL_ALL);
 204         ASSERT(cvd->vdev_parent == NULL);
 205 
 206         cvd->vdev_parent = pvd;
 207 
 208         if (pvd == NULL)
 209                 return;
 210 
 211         ASSERT(id >= pvd->vdev_children || pvd->vdev_child[id] == NULL);
 212 
 213         oldsize = pvd->vdev_children * sizeof (vdev_t *);
 214         pvd->vdev_children = MAX(pvd->vdev_children, id + 1);
 215         newsize = pvd->vdev_children * sizeof (vdev_t *);