summaryrefslogtreecommitdiff
path: root/usr/src
diff options
context:
space:
mode:
authorToomas Soome <tsoome@me.com>2017-09-11 17:05:18 +0300
committerRichard Lowe <richlowe@richlowe.net>2017-10-06 18:04:09 -0400
commitf905073d4c7083276dd5510a7006d2e98c6ec032 (patch)
tree02bfdb76eb1aa01ec5a615276a37a78a47a76c5c /usr/src
parent64ee6612ceb686fa3f41561cf589072ebb0132b1 (diff)
downloadillumos-joyent-f905073d4c7083276dd5510a7006d2e98c6ec032.tar.gz
8647 loader should support large_dnode
Reviewed by: Dan McDonald <danmcd@joyent.com> Reviewed by: Ken Mays <maybird1776@yahoo.com> Approved by: Richard Lowe <richlowe@richlowe.net>
Diffstat (limited to 'usr/src')
-rw-r--r--usr/src/boot/Makefile.version2
-rw-r--r--usr/src/boot/sys/boot/zfs/zfsimpl.c7
-rw-r--r--usr/src/boot/sys/cddl/boot/zfs/zfsimpl.h55
3 files changed, 52 insertions, 12 deletions
diff --git a/usr/src/boot/Makefile.version b/usr/src/boot/Makefile.version
index a90435f0cd..427065c3be 100644
--- a/usr/src/boot/Makefile.version
+++ b/usr/src/boot/Makefile.version
@@ -33,4 +33,4 @@ LOADER_VERSION = 1.1
# Use date like formatting here, YYYY.MM.DD.XX, without leading zeroes.
# The version is processed from left to right, the version number can only
# be increased.
-BOOT_VERSION = $(LOADER_VERSION)-2017.8.31.1
+BOOT_VERSION = $(LOADER_VERSION)-2017.9.11.1
diff --git a/usr/src/boot/sys/boot/zfs/zfsimpl.c b/usr/src/boot/sys/boot/zfs/zfsimpl.c
index 9257fcf2cc..f34f88d88e 100644
--- a/usr/src/boot/sys/boot/zfs/zfsimpl.c
+++ b/usr/src/boot/sys/boot/zfs/zfsimpl.c
@@ -58,6 +58,7 @@ static const char *features_for_read[] = {
"com.delphix:embedded_data",
"org.open-zfs:large_blocks",
"org.illumos:sha512",
+ "org.zfsonlinux:large_dnode",
NULL
};
@@ -415,7 +416,7 @@ vdev_read_phys(vdev_t *vdev, const blkptr_t *bp, void *buf,
psize = size;
}
- /*printf("ZFS: reading %d bytes at 0x%jx to %p\n", psize, (uintmax_t)offset, buf);*/
+ /*printf("ZFS: reading %zu bytes at 0x%jx to %p\n", psize, (uintmax_t)offset, buf);*/
rc = vdev->v_phys_read(vdev, vdev->v_read_priv, offset, buf, psize);
if (rc)
return (rc);
@@ -2200,7 +2201,7 @@ zfs_dnode_stat(const spa_t *spa, dnode_phys_t *dn, struct stat *sb)
sahdrp = (sa_hdr_phys_t *)DN_BONUS(dn);
else {
if ((dn->dn_flags & DNODE_FLAG_SPILL_BLKPTR) != 0) {
- blkptr_t *bp = &dn->dn_spill;
+ blkptr_t *bp = DN_SPILL_BLKPTR(dn);
int error;
size = BP_GET_LSIZE(bp);
@@ -2250,7 +2251,7 @@ zfs_dnode_readlink(const spa_t *spa, dnode_phys_t *dn, char *path, size_t psize)
if ((dn->dn_flags & DNODE_FLAG_SPILL_BLKPTR) == 0)
return (EIO);
- bp = &dn->dn_spill;
+ bp = DN_SPILL_BLKPTR(dn);
size = BP_GET_LSIZE(bp);
buf = zfs_alloc(size);
diff --git a/usr/src/boot/sys/cddl/boot/zfs/zfsimpl.h b/usr/src/boot/sys/cddl/boot/zfs/zfsimpl.h
index a88d256f8a..0c3f1a640f 100644
--- a/usr/src/boot/sys/cddl/boot/zfs/zfsimpl.h
+++ b/usr/src/boot/sys/cddl/boot/zfs/zfsimpl.h
@@ -860,10 +860,19 @@ struct uberblock {
/*
* Derived constants.
*/
-#define DNODE_SIZE (1 << DNODE_SHIFT)
-#define DN_MAX_NBLKPTR ((DNODE_SIZE - DNODE_CORE_SIZE) >> SPA_BLKPTRSHIFT)
-#define DN_MAX_BONUSLEN (DNODE_SIZE - DNODE_CORE_SIZE - (1 << SPA_BLKPTRSHIFT))
-#define DN_MAX_OBJECT (1ULL << DN_MAX_OBJECT_SHIFT)
+#define DNODE_MIN_SIZE (1 << DNODE_SHIFT)
+#define DNODE_MAX_SIZE (1 << DNODE_BLOCK_SHIFT)
+#define DNODE_BLOCK_SIZE (1 << DNODE_BLOCK_SHIFT)
+#define DNODE_MIN_SLOTS (DNODE_MIN_SIZE >> DNODE_SHIFT)
+#define DNODE_MAX_SLOTS (DNODE_MAX_SIZE >> DNODE_SHIFT)
+#define DN_BONUS_SIZE(dnsize) ((dnsize) - DNODE_CORE_SIZE - \
+ (1 << SPA_BLKPTRSHIFT))
+#define DN_SLOTS_TO_BONUSLEN(slots) DN_BONUS_SIZE((slots) << DNODE_SHIFT)
+#define DN_OLD_MAX_BONUSLEN (DN_BONUS_SIZE(DNODE_MIN_SIZE))
+#define DN_MAX_NBLKPTR ((DNODE_MIN_SIZE - DNODE_CORE_SIZE) >> \
+ SPA_BLKPTRSHIFT)
+#define DN_MAX_OBJECT (1ULL << DN_MAX_OBJECT_SHIFT)
+#define DN_ZERO_BONUSLEN (DN_BONUS_SIZE(DNODE_MAX_SIZE) + 1)
#define DNODES_PER_BLOCK_SHIFT (DNODE_BLOCK_SHIFT - DNODE_SHIFT)
#define DNODES_PER_BLOCK (1ULL << DNODES_PER_BLOCK_SHIFT)
@@ -899,7 +908,8 @@ typedef struct dnode_phys {
uint8_t dn_flags; /* DNODE_FLAG_* */
uint16_t dn_datablkszsec; /* data block size in 512b sectors */
uint16_t dn_bonuslen; /* length of dn_bonus */
- uint8_t dn_pad2[4];
+ uint8_t dn_extra_slots; /* # of subsequent slots consumed */
+ uint8_t dn_pad2[3];
/* accounting is protected by dn_dirty_mtx */
uint64_t dn_maxblkid; /* largest allocated block ID */
@@ -907,11 +917,40 @@ typedef struct dnode_phys {
uint64_t dn_pad3[4];
- blkptr_t dn_blkptr[1];
- uint8_t dn_bonus[DN_MAX_BONUSLEN - sizeof (blkptr_t)];
- blkptr_t dn_spill;
+ /*
+ * The tail region is 448 bytes for a 512 byte dnode, and
+ * correspondingly larger for larger dnode sizes. The spill
+ * block pointer, when present, is always at the end of the tail
+ * region. There are three ways this space may be used, using
+ * a 512 byte dnode for this diagram:
+ *
+ * 0 64 128 192 256 320 384 448 (offset)
+ * +---------------+---------------+---------------+-------+
+ * | dn_blkptr[0] | dn_blkptr[1] | dn_blkptr[2] | / |
+ * +---------------+---------------+---------------+-------+
+ * | dn_blkptr[0] | dn_bonus[0..319] |
+ * +---------------+-----------------------+---------------+
+ * | dn_blkptr[0] | dn_bonus[0..191] | dn_spill |
+ * +---------------+-----------------------+---------------+
+ */
+ union {
+ blkptr_t dn_blkptr[1+DN_OLD_MAX_BONUSLEN/sizeof (blkptr_t)];
+ struct {
+ blkptr_t __dn_ignore1;
+ uint8_t dn_bonus[DN_OLD_MAX_BONUSLEN];
+ };
+ struct {
+ blkptr_t __dn_ignore2;
+ uint8_t __dn_ignore3[DN_OLD_MAX_BONUSLEN -
+ sizeof (blkptr_t)];
+ blkptr_t dn_spill;
+ };
+ };
} dnode_phys_t;
+#define DN_SPILL_BLKPTR(dnp) (blkptr_t *)((char *)(dnp) + \
+ (((dnp)->dn_extra_slots + 1) << DNODE_SHIFT) - (1 << SPA_BLKPTRSHIFT))
+
typedef enum dmu_object_byteswap {
DMU_BSWAP_UINT8,
DMU_BSWAP_UINT16,