Skip to content

Commit 80edc68

Browse files
author
Paul Dagnelie
committed
Implement dynamic gang header sizes
ZFS gang block headers are currently fixed at 512 bytes. This is increasingly wasteful in the era of larger disk sector sizes. This PR allows any size allocation to work as a gang header. It also contains supporting changes to ZDB to make gang headers easier to work with. Sponsored-by: Klara, Inc. Sponsored-by: Wasabi Technology, Inc. Signed-off-by: Paul Dagnelie <[email protected]>
1 parent 69ee01a commit 80edc68

File tree

24 files changed

+4546
-10438
lines changed

24 files changed

+4546
-10438
lines changed

cmd/zdb/zdb.c

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8588,9 +8588,9 @@ zdb_dump_indirect(blkptr_t *bp, int nbps, int flags)
85888588
}
85898589

85908590
static void
8591-
zdb_dump_gbh(void *buf, int flags)
8591+
zdb_dump_gbh(void *buf, uint64_t size, int flags)
85928592
{
8593-
zdb_dump_indirect((blkptr_t *)buf, SPA_GBH_NBLKPTRS, flags);
8593+
zdb_dump_indirect((blkptr_t *)buf, gbh_nblkptrs(size), flags);
85948594
}
85958595

85968596
static void
@@ -9073,7 +9073,7 @@ zdb_read_block(char *thing, spa_t *spa)
90739073
zdb_dump_indirect((blkptr_t *)buf,
90749074
orig_lsize / sizeof (blkptr_t), flags);
90759075
else if (flags & ZDB_FLAG_GBH)
9076-
zdb_dump_gbh(buf, flags);
9076+
zdb_dump_gbh(buf, lsize, flags);
90779077
else
90789078
zdb_dump_block(thing, buf, lsize, flags);
90799079

cmd/zpool/zpool_main.c

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11330,7 +11330,8 @@ upgrade_enable_all(zpool_handle_t *zhp, int *countp)
1133011330
const char *fname = spa_feature_table[i].fi_uname;
1133111331
const char *fguid = spa_feature_table[i].fi_guid;
1133211332

11333-
if (!spa_feature_table[i].fi_zfs_mod_supported)
11333+
if (!spa_feature_table[i].fi_zfs_mod_supported ||
11334+
(spa_feature_table[i].fi_flags & ZFEATURE_FLAG_NO_UPGRADE))
1133411335
continue;
1133511336

1133611337
if (!nvlist_exists(enabled, fguid) && requested_features[i]) {
@@ -11485,7 +11486,11 @@ upgrade_list_disabled_cb(zpool_handle_t *zhp, void *arg)
1148511486
"Note that the pool "
1148611487
"'compatibility' feature can be "
1148711488
"used to inhibit\nfeature "
11488-
"upgrades.\n\n"));
11489+
"upgrades.\n\n"
11490+
"Features marked with (*) are not "
11491+
"applied automatically on upgrade, "
11492+
"and\nmust be applied explicitly "
11493+
"with zpool-set(7).\n\n"));
1148911494
(void) printf(gettext("POOL "
1149011495
"FEATURE\n"));
1149111496
(void) printf(gettext("------"
@@ -11499,7 +11504,9 @@ upgrade_list_disabled_cb(zpool_handle_t *zhp, void *arg)
1149911504
poolfirst = B_FALSE;
1150011505
}
1150111506

11502-
(void) printf(gettext(" %s\n"), fname);
11507+
(void) printf(gettext(" %s%s\n"), fname,
11508+
spa_feature_table[i].fi_flags &
11509+
ZFEATURE_FLAG_NO_UPGRADE ? "(*)" : "");
1150311510
}
1150411511
/*
1150511512
* If they did "zpool upgrade -a", then we could

include/sys/vdev.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -148,7 +148,7 @@ extern uint64_t vdev_psize_to_asize(vdev_t *vd, uint64_t psize);
148148
static inline uint64_t
149149
vdev_gang_header_asize(vdev_t *vd)
150150
{
151-
return (vdev_psize_to_asize_txg(vd, SPA_GANGBLOCKSIZE, 0));
151+
return (vdev_psize_to_asize_txg(vd, SPA_OLD_GANGBLOCKSIZE, 0));
152152
}
153153

154154
extern int vdev_fault(spa_t *spa, uint64_t guid, vdev_aux_t aux);

include/sys/zio.h

Lines changed: 15 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -61,19 +61,18 @@ typedef struct zio_eck {
6161
* Gang block headers are self-checksumming and contain an array
6262
* of block pointers.
6363
*/
64-
#define SPA_GANGBLOCKSIZE SPA_MINBLOCKSIZE
65-
#define SPA_GBH_NBLKPTRS ((SPA_GANGBLOCKSIZE - \
66-
sizeof (zio_eck_t)) / sizeof (blkptr_t))
67-
#define SPA_GBH_FILLER ((SPA_GANGBLOCKSIZE - \
68-
sizeof (zio_eck_t) - \
69-
(SPA_GBH_NBLKPTRS * sizeof (blkptr_t))) /\
70-
sizeof (uint64_t))
71-
72-
typedef struct zio_gbh {
73-
blkptr_t zg_blkptr[SPA_GBH_NBLKPTRS];
74-
uint64_t zg_filler[SPA_GBH_FILLER];
75-
zio_eck_t zg_tail;
76-
} zio_gbh_phys_t;
64+
#define SPA_OLD_GANGBLOCKSIZE SPA_MINBLOCKSIZE
65+
typedef void zio_gbh_phys_t;
66+
67+
static inline uint64_t
68+
gbh_nblkptrs(uint64_t size) {
69+
return ((size - sizeof (zio_eck_t)) / sizeof (blkptr_t));
70+
}
71+
72+
static inline zio_eck_t *
73+
gbh_eck(zio_gbh_phys_t *gbh, uint64_t size) {
74+
return ((zio_eck_t *)((uintptr_t)gbh + size - sizeof (zio_eck_t)));
75+
}
7776

7877
enum zio_checksum {
7978
ZIO_CHECKSUM_INHERIT = 0,
@@ -399,7 +398,9 @@ typedef struct zio_vsd_ops {
399398

400399
typedef struct zio_gang_node {
401400
zio_gbh_phys_t *gn_gbh;
402-
struct zio_gang_node *gn_child[SPA_GBH_NBLKPTRS];
401+
uint64_t gn_gangblocksize;
402+
uint64_t gn_allocsize;
403+
struct zio_gang_node *gn_child[];
403404
} zio_gang_node_t;
404405

405406
typedef zio_t *zio_gang_issue_func_t(zio_t *zio, blkptr_t *bp,

include/zfeature_common.h

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,7 @@ typedef enum spa_feature {
8787
SPA_FEATURE_FAST_DEDUP,
8888
SPA_FEATURE_LONGNAME,
8989
SPA_FEATURE_LARGE_MICROZAP,
90+
SPA_FEATURE_DYNAMIC_GANG_HEADER,
9091
SPA_FEATURES
9192
} spa_feature_t;
9293

@@ -103,7 +104,15 @@ typedef enum zfeature_flags {
103104
/* Activate this feature at the same time it is enabled. */
104105
ZFEATURE_FLAG_ACTIVATE_ON_ENABLE = (1 << 2),
105106
/* Each dataset has a field set if it has ever used this feature. */
106-
ZFEATURE_FLAG_PER_DATASET = (1 << 3)
107+
ZFEATURE_FLAG_PER_DATASET = (1 << 3),
108+
/*
109+
* This feature isn't enabled by zpool upgrade; it must be explicitly
110+
* listed to be enabled. It will also be applied if listed in an
111+
* explicitly provided compatibility list. This flag can be removed
112+
* from a given feature once support is sufficiently widespread, or
113+
* worries about backwards compatibility are no longer relevant.
114+
*/
115+
ZFEATURE_FLAG_NO_UPGRADE = (1 << 4)
107116
} zfeature_flags_t;
108117

109118
typedef enum zfeature_type {

0 commit comments

Comments
 (0)