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,
_______________________________________________
svn-src-head@freebsd.org mailing list
https://lists.freebsd.org/mailman/listinfo/svn-src-head
To unsubscribe, send any mail to "svn-src-head-unsubscr...@freebsd.org"

Reply via email to