Skip site navigation (1)Skip section navigation (2)
Date:      Tue, 12 Sep 2017 13:45:04 +0000 (UTC)
From:      Toomas Soome <tsoome@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r323494 - in head/sys: boot/zfs cddl/boot/zfs
Message-ID:  <201709121345.v8CDj401040971@repo.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: tsoome
Date: Tue Sep 12 13:45:04 2017
New Revision: 323494
URL: https://svnweb.freebsd.org/changeset/base/323494

Log:
  loader should support large_dnode
  
  The zfsonlinux feature large_dnode is not yet supported by the loader.
  
  Reviewed by:	avg, allanjude
  Differential Revision:	https://reviews.freebsd.org/D12288

Modified:
  head/sys/boot/zfs/zfsimpl.c
  head/sys/cddl/boot/zfs/zfsimpl.h

Modified: head/sys/boot/zfs/zfsimpl.c
==============================================================================
--- head/sys/boot/zfs/zfsimpl.c	Tue Sep 12 13:39:44 2017	(r323493)
+++ head/sys/boot/zfs/zfsimpl.c	Tue Sep 12 13:45:04 2017	(r323494)
@@ -60,6 +60,7 @@ static const char *features_for_read[] = {
 	"org.open-zfs:large_blocks",
 	"org.illumos:sha512",
 	"org.illumos:skein",
+	"org.zfsonlinux:large_dnode",
 	NULL
 };
 
@@ -420,7 +421,7 @@ vdev_read_phys(vdev_t *vdev, const blkptr_t *bp, void 
 		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);
@@ -2280,7 +2281,7 @@ zfs_dnode_stat(const spa_t *spa, dnode_phys_t *dn, str
 			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);
@@ -2330,7 +2331,7 @@ zfs_dnode_readlink(const spa_t *spa, dnode_phys_t *dn,
 
 			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);

Modified: head/sys/cddl/boot/zfs/zfsimpl.h
==============================================================================
--- head/sys/cddl/boot/zfs/zfsimpl.h	Tue Sep 12 13:39:44 2017	(r323493)
+++ head/sys/cddl/boot/zfs/zfsimpl.h	Tue Sep 12 13:45:04 2017	(r323494)
@@ -859,10 +859,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)
@@ -898,7 +907,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 */
@@ -906,10 +916,39 @@ 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,



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201709121345.v8CDj401040971>