Skip to content

Commit

Permalink
Merge pull request #151 from truenas/spa-min-alloc-2.1
Browse files Browse the repository at this point in the history
[2.1] spa_min_alloc should be GCD, not min
  • Loading branch information
ixhamza authored Jul 25, 2023
2 parents 6a1d855 + a8da845 commit 62ffa8d
Show file tree
Hide file tree
Showing 4 changed files with 51 additions and 9 deletions.
1 change: 1 addition & 0 deletions include/sys/spa_impl.h
Original file line number Diff line number Diff line change
Expand Up @@ -249,6 +249,7 @@ struct spa {
uint64_t spa_min_ashift; /* of vdevs in normal class */
uint64_t spa_max_ashift; /* of vdevs in normal class */
uint64_t spa_min_alloc; /* of vdevs in normal class */
uint64_t spa_gcd_alloc; /* of vdevs in normal class */
uint64_t spa_config_guid; /* config pool guid */
uint64_t spa_load_guid; /* spa_load initialized guid */
uint64_t spa_last_synced_guid; /* last synced guid */
Expand Down
1 change: 1 addition & 0 deletions module/zfs/spa_misc.c
Original file line number Diff line number Diff line change
Expand Up @@ -773,6 +773,7 @@ spa_add(const char *name, nvlist_t *config, const char *altroot)
spa->spa_min_ashift = INT_MAX;
spa->spa_max_ashift = 0;
spa->spa_min_alloc = INT_MAX;
spa->spa_gcd_alloc = INT_MAX;

/* Reset cached value */
spa->spa_dedup_dspace = ~0ULL;
Expand Down
36 changes: 32 additions & 4 deletions module/zfs/vdev.c
Original file line number Diff line number Diff line change
Expand Up @@ -1351,6 +1351,36 @@ vdev_remove_parent(vdev_t *cvd)
vdev_free(mvd);
}

/*
* Choose GCD for spa_gcd_alloc.
*/
static uint64_t
vdev_gcd(uint64_t a, uint64_t b)
{
while (b != 0) {
uint64_t t = b;
b = a % b;
a = t;
}
return (a);
}

/*
* Set spa_min_alloc and spa_gcd_alloc.
*/
static void
vdev_spa_set_alloc(spa_t *spa, uint64_t min_alloc)
{
if (min_alloc < spa->spa_min_alloc)
spa->spa_min_alloc = min_alloc;
if (spa->spa_gcd_alloc == INT_MAX) {
spa->spa_gcd_alloc = min_alloc;
} else {
spa->spa_gcd_alloc = vdev_gcd(min_alloc,
spa->spa_gcd_alloc);
}
}

void
vdev_metaslab_group_create(vdev_t *vd)
{
Expand Down Expand Up @@ -1403,8 +1433,7 @@ vdev_metaslab_group_create(vdev_t *vd)
spa->spa_min_ashift = vd->vdev_ashift;

uint64_t min_alloc = vdev_get_min_alloc(vd);
if (min_alloc < spa->spa_min_alloc)
spa->spa_min_alloc = min_alloc;
vdev_spa_set_alloc(spa, min_alloc);
}
}
}
Expand Down Expand Up @@ -2162,8 +2191,7 @@ vdev_open(vdev_t *vd)
if (vd->vdev_top == vd && vd->vdev_ashift != 0 &&
vd->vdev_islog == 0 && vd->vdev_aux == NULL) {
uint64_t min_alloc = vdev_get_min_alloc(vd);
if (min_alloc < spa->spa_min_alloc)
spa->spa_min_alloc = min_alloc;
vdev_spa_set_alloc(spa, min_alloc);
}

/*
Expand Down
22 changes: 17 additions & 5 deletions module/zfs/zio.c
Original file line number Diff line number Diff line change
Expand Up @@ -1529,6 +1529,19 @@ zio_shrink(zio_t *zio, uint64_t size)
}
}

/*
* Round provided allocation size up to a value that can be allocated
* by at least some vdev(s) in the pool with minimum or no additional
* padding and without extra space usage on others
*/
static uint64_t
zio_roundup_alloc_size(spa_t *spa, uint64_t size)
{
if (size > spa->spa_min_alloc)
return (roundup(size, spa->spa_gcd_alloc));
return (spa->spa_min_alloc);
}

/*
* ==========================================================================
* Prepare to read and write logical blocks
Expand Down Expand Up @@ -1735,9 +1748,8 @@ zio_write_compress(zio_t *zio)
* in that we charge for the padding used to fill out
* the last sector.
*/
ASSERT3U(spa->spa_min_alloc, >=, SPA_MINBLOCKSHIFT);
size_t rounded = (size_t)roundup(psize,
spa->spa_min_alloc);
size_t rounded = (size_t)zio_roundup_alloc_size(spa,
psize);
if (rounded >= lsize) {
compress = ZIO_COMPRESS_OFF;
zio_buf_free(cbuf, lsize);
Expand Down Expand Up @@ -1780,8 +1792,8 @@ zio_write_compress(zio_t *zio)
* take this codepath because it will change the on-disk block
* and decryption will fail.
*/
size_t rounded = MIN((size_t)roundup(psize,
spa->spa_min_alloc), lsize);
size_t rounded = MIN((size_t)zio_roundup_alloc_size(spa, psize),
lsize);

if (rounded != psize) {
abd_t *cdata = abd_alloc_linear(rounded, B_TRUE);
Expand Down

0 comments on commit 62ffa8d

Please sign in to comment.