この記事では、実用的な例で、zfsがデータを保存する方法と場所を分析します。
データに直接アクセスするには、zdbユーティリティを使用しませんが、radare2を使用して、ディスクに書き込まれたバイトを直接調べてみます。
zfsについて
Zfs(Zettabyte File System)は、Solarisオペレーティングシステム用にSunで作成されたCOW(コピーオンライト)ファイルシステムです。
このファイルシステムの主な利点の1つは、メタデータだけでなくユーザーデータにもチェックサムを使用することです。
ZFSディスク構造
zfsコンポーネントの詳細については、Sunの公式のZFS On-Disk Specificationドキュメントを参照することをお勧めします。
仮想デバイス
zfsプールは仮想デバイス(以降vdev)で構成されます。 これ以上詳細な情報は必要ないので、さらに先に進みます。 これ以上詳細な情報は必要ありませんので、先に進みます。vdevには、論理仮想デバイスと物理仮想デバイスの2つのタイプがあります。
ラベル
各物理仮想デバイスには、4つのラベル(図では、L0、L1、L2、およびL3)が格納されています。

ブートブロック
L0およびL1タグの直後に、3.5 MBのスペースが将来の使用のために予約されています。
Uberblockの基準点
他のzfsオブジェクトとは異なり、ラベルの位置は厳密に固定されており、2つのステップで更新されます。ラベルL0とL2が最初に更新され、次にL1とL3が更新されます。 この記事では、レーベルに記録されたデータのうち、uberblockのみが興味を持ちます。詳細に検討します。
ユーバーブロック
Uberblockは次の構造で表されます。
struct uberblock { uint64_t ub_magic; /* UBERBLOCK_MAGIC */ uint64_t ub_version; /* SPA_VERSION */ uint64_t ub_txg; /* txg of last sync */ uint64_t ub_guid_sum; /* sum of all vdev guids */ uint64_t ub_timestamp; /* UTC time of last sync */ blkptr_t ub_rootbp; /* MOS objset_phys_t */ /* highest SPA_VERSION supported by software that wrote this txg */ uint64_t ub_software_version; };
いくつかのフィールドを説明しましょう:
ub_txg
取引番号
ub_timestamp
Uberblock記録時間を含む(UTC形式)
ub_rootbp
メタオブジェクトセットへのリンク(zfsでは、ブロックへのリンクはblkptr_t構造で表されます。これについては以下で説明します)。
ブロック参照(blkptr_t)
ブロック参照は、次の構造を表します。
typedef struct blkptr { dva_t blk_dva[SPA_DVAS_PER_BP]; /* Data Virtual Addresses */ uint64_t blk_prop; /* size, compression, type, etc */ uint64_t blk_pad[2]; /* Extra space for the future */ uint64_t blk_phys_birth; /* txg when block was allocated */ uint64_t blk_birth; /* transaction group at birth */ uint64_t blk_fill; /* fill count */ zio_cksum_t blk_cksum; /* 256-bit checksum */ } blkptr_t; /* * All SPA data is represented by 128-bit data virtual addresses (DVAs). * The members of the dva_t should be considered opaque outside the SPA. */ typedef struct dva { uint64_t dva_word[2]; } dva_t; /* * Each block has a 256-bit checksum -- strong enough for cryptographic hashes. */ typedef struct zio_cksum { uint64_t zc_word[4]; } zio_cksum_t;
バイト配列の形式で表すと、次の画像が得られます

最も重要な分野
dva_t
データの仮想アドレス。 オフセットフィールドには、オフセットがセクター(512バイト)で格納されます。
上の画像では、これらは0〜5行目です。
blk_prop
対応するフィールドには、タイプ、サイズ、ブロックの間接性のレベルなどが含まれます。
タイプはdmu_object_typeのリストに変換されます。 そして、それぞれzio_checksumとzio_compressのcksumとcompフィールド。
typedef enum dmu_object_type { DMU_OT_NONE, /* general: */ DMU_OT_OBJECT_DIRECTORY, /* ZAP */ DMU_OT_OBJECT_ARRAY, /* UINT64 */ DMU_OT_PACKED_NVLIST, /* UINT8 (XDR by nvlist_pack/unpack) */ DMU_OT_PACKED_NVLIST_SIZE, /* UINT64 */ DMU_OT_BPOBJ, /* UINT64 */ DMU_OT_BPOBJ_HDR, /* UINT64 */ /* spa: */ DMU_OT_SPACE_MAP_HEADER, /* UINT64 */ DMU_OT_SPACE_MAP, /* UINT64 */ /* zil: */ DMU_OT_INTENT_LOG, /* UINT64 */ /* dmu: */ DMU_OT_DNODE, /* DNODE */ DMU_OT_OBJSET, /* OBJSET */ /* dsl: */ DMU_OT_DSL_DIR, /* UINT64 */ DMU_OT_DSL_DIR_CHILD_MAP, /* ZAP */ DMU_OT_DSL_DS_SNAP_MAP, /* ZAP */ DMU_OT_DSL_PROPS, /* ZAP */ DMU_OT_DSL_DATASET, /* UINT64 */ /* zpl: */ DMU_OT_ZNODE, /* ZNODE */ DMU_OT_OLDACL, /* Old ACL */ DMU_OT_PLAIN_FILE_CONTENTS, /* UINT8 */ DMU_OT_DIRECTORY_CONTENTS, /* ZAP */ DMU_OT_MASTER_NODE, /* ZAP */ DMU_OT_UNLINKED_SET, /* ZAP */ /* zvol: */ DMU_OT_ZVOL, /* UINT8 */ DMU_OT_ZVOL_PROP, /* ZAP */ /* other; for testing only! */ DMU_OT_PLAIN_OTHER, /* UINT8 */ DMU_OT_UINT64_OTHER, /* UINT64 */ DMU_OT_ZAP_OTHER, /* ZAP */ /* new object types: */ DMU_OT_ERROR_LOG, /* ZAP */ DMU_OT_SPA_HISTORY, /* UINT8 */ DMU_OT_SPA_HISTORY_OFFSETS, /* spa_his_phys_t */ DMU_OT_POOL_PROPS, /* ZAP */ DMU_OT_DSL_PERMS, /* ZAP */ DMU_OT_ACL, /* ACL */ DMU_OT_SYSACL, /* SYSACL */ DMU_OT_FUID, /* FUID table (Packed NVLIST UINT8) */ DMU_OT_FUID_SIZE, /* FUID table size UINT64 */ DMU_OT_NEXT_CLONES, /* ZAP */ DMU_OT_SCAN_QUEUE, /* ZAP */ DMU_OT_USERGROUP_USED, /* ZAP */ DMU_OT_USERGROUP_QUOTA, /* ZAP */ DMU_OT_USERREFS, /* ZAP */ DMU_OT_DDT_ZAP, /* ZAP */ DMU_OT_DDT_STATS, /* ZAP */ DMU_OT_SA, /* System attr */ DMU_OT_SA_MASTER_NODE, /* ZAP */ DMU_OT_SA_ATTR_REGISTRATION, /* ZAP */ DMU_OT_SA_ATTR_LAYOUTS, /* ZAP */ DMU_OT_SCAN_XLATE, /* ZAP */ DMU_OT_DEDUP, /* fake dedup BP from ddt_bp_create() */ DMU_OT_DEADLIST, /* ZAP */ DMU_OT_DEADLIST_HDR, /* UINT64 */ DMU_OT_DSL_CLONES, /* ZAP */ DMU_OT_BPOBJ_SUBOBJ, /* UINT64 */ /* * Do not allocate new object types here. Doing so makes the on-disk * format incompatible with any other format that uses the same object * type number. * * When creating an object which does not have one of the above types * use the DMU_OTN_* type with the correct byteswap and metadata * values. * * The DMU_OTN_* types do not have entries in the dmu_ot table, * use the DMU_OT_IS_METDATA() and DMU_OT_BYTESWAP() macros instead * of indexing into dmu_ot directly (this works for both DMU_OT_* types * and DMU_OTN_* types). */ DMU_OT_NUMTYPES, /* * Names for valid types declared with DMU_OT(). */ DMU_OTN_UINT8_DATA = DMU_OT(DMU_BSWAP_UINT8, B_FALSE), DMU_OTN_UINT8_METADATA = DMU_OT(DMU_BSWAP_UINT8, B_TRUE), DMU_OTN_UINT16_DATA = DMU_OT(DMU_BSWAP_UINT16, B_FALSE), DMU_OTN_UINT16_METADATA = DMU_OT(DMU_BSWAP_UINT16, B_TRUE), DMU_OTN_UINT32_DATA = DMU_OT(DMU_BSWAP_UINT32, B_FALSE), DMU_OTN_UINT32_METADATA = DMU_OT(DMU_BSWAP_UINT32, B_TRUE), DMU_OTN_UINT64_DATA = DMU_OT(DMU_BSWAP_UINT64, B_FALSE), DMU_OTN_UINT64_METADATA = DMU_OT(DMU_BSWAP_UINT64, B_TRUE), DMU_OTN_ZAP_DATA = DMU_OT(DMU_BSWAP_ZAP, B_FALSE), DMU_OTN_ZAP_METADATA = DMU_OT(DMU_BSWAP_ZAP, B_TRUE), } dmu_object_type_t;
zio_checksumおよびzio_compressのリストを以下に示します。
enum zio_checksum { ZIO_CHECKSUM_INHERIT = 0, ZIO_CHECKSUM_ON, ZIO_CHECKSUM_OFF, ZIO_CHECKSUM_LABEL, ZIO_CHECKSUM_GANG_HEADER, ZIO_CHECKSUM_ZILOG, ZIO_CHECKSUM_FLETCHER_2, ZIO_CHECKSUM_FLETCHER_4, ZIO_CHECKSUM_SHA256, ZIO_CHECKSUM_ZILOG2, ZIO_CHECKSUM_FUNCTIONS };
enum zio_compress { ZIO_COMPRESS_INHERIT = 0, ZIO_COMPRESS_ON, ZIO_COMPRESS_OFF, ZIO_COMPRESS_LZJB, ZIO_COMPRESS_EMPTY, ZIO_COMPRESS_GZIP_1, ZIO_COMPRESS_GZIP_2, ZIO_COMPRESS_GZIP_3, ZIO_COMPRESS_GZIP_4, ZIO_COMPRESS_GZIP_5, ZIO_COMPRESS_GZIP_6, ZIO_COMPRESS_GZIP_7, ZIO_COMPRESS_GZIP_8, ZIO_COMPRESS_GZIP_9, ZIO_COMPRESS_ZLE, ZIO_COMPRESS_LZ4, ZIO_COMPRESS_FUNCTIONS };
オブジェクト(dnode)
uberblockを除き、他のすべてのエンティティ(メタデータとユーザーデータ)はオブジェクトとして表されます。 dmu_object_type列挙は、可能なオブジェクトタイプをリストします。
オブジェクトは、以下に示すdnode_phys構造体によって記述されます。
typedef struct dnode_phys { uint8_t dn_type; /* dmu_object_type_t */ uint8_t dn_indblkshift; /* ln2(indirect block size) */ uint8_t dn_nlevels; /* 1=dn_blkptr->data blocks */ uint8_t dn_nblkptr; /* length of dn_blkptr */ uint8_t dn_bonustype; /* type of data in bonus buffer */ uint8_t dn_checksum; /* ZIO_CHECKSUM type */ uint8_t dn_compress; /* ZIO_COMPRESS type */ 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]; /* accounting is protected by dn_dirty_mtx */ uint64_t dn_maxblkid; /* largest allocated block ID */ uint64_t dn_used; /* bytes (or sectors) of disk space */ uint64_t dn_pad3[4]; union { blkptr_t dn_blkptr[1+DN_MAX_BONUSLEN/sizeof (blkptr_t)]; struct { blkptr_t __dn_ignore1; uint8_t dn_bonus[DN_MAX_BONUSLEN]; }; struct { blkptr_t __dn_ignore2; uint8_t __dn_ignore3[DN_MAX_BONUSLEN-sizeof (blkptr_t)]; blkptr_t dn_spill; }; }; } dnode_phys_t; typedef struct zil_header { uint64_t zh_claim_txg; /* txg in which log blocks were claimed */ uint64_t zh_replay_seq; /* highest replayed sequence number */ blkptr_t zh_log; /* log chain */ uint64_t zh_claim_blk_seq; /* highest claimed block sequence number */ uint64_t zh_flags; /* header flags */ uint64_t zh_claim_lr_seq; /* highest claimed lr sequence number */ uint64_t zh_pad[3]; } zil_header_t;
オブジェクトのセット
Zfsオブジェクトは、いわゆるオブジェクトセット(objset)にグループ化でき、次のタイプで表されます。
typedef enum dmu_objset_type { DMU_OST_NONE, DMU_OST_META, /* MOS */ DMU_OST_ZFS, /* Dataset DMU_OST_ZVOL, /* zfs (vol) DMU_OST_OTHER, /* For testing only! */ DMU_OST_ANY, /* Be careful! */ DMU_OST_NUMTYPES } dmu_objset_type_t;
オブジェクトのセット自体は、次のような2キロバイトの構造で表されます。
typedef struct objset_phys { dnode_phys_t os_meta_dnode; zil_header_t os_zil_header; uint64_t os_type; uint64_t os_flags; char os_pad[OBJSET_PHYS_SIZE - sizeof (dnode_phys_t)*3 - sizeof (zil_header_t) - sizeof (uint64_t)*2]; dnode_phys_t os_userused_dnode; dnode_phys_t os_groupused_dnode; } objset_phys_t;
バイトを見る
この記事では、101メガバイトのファイルに基づいたテストプールを使用します。
なぜ101 MBなのか 実際のところ、zfsは空き領域(256KBの4xタグと3.5メガバイトのブートブロックを除く)を固定ブロックに分割します( ZFSの仕組み-パート1:vdevを参照)。 100 MBのディスクの場合、ブロックサイズは16 MBであり、そのようなブロックの100 MBのディスクの場合、5つだけが適合し、使用可能なボリュームは80 MBになります。 ただし、このようなブロックのうち101MBの場合、6個がすでに収まり、使用可能なボリュームは96MBに増加します。 この記事はそれほど重要ではありませんが。 しかし、たとえば、4TBディスクの場合、zfsに完全に渡すと、13GBを超える「失われた」スペースが得られます。
3725「バイナリ」GBはそれぞれ16 GBのブロックに分割され、13 GBの残りは使用されません。
テストプールを作成する
# dd if=/dev/zero of=/tmp/test_disk bs=1M count=101
101+0
101+0
105906176 (106 MB, 101 MiB) , 0,0847695 s, 1,2 GB/s
#zpool create test -o ashift=9 /tmp/test_disk
recordsizeを512バイトに設定し、いくつかのファイルを追加します。
# zfs set recordsize=512 test
# dd if=/dev/urandom of=/test/0B bs=1 count=0
0+0
0+0
0 , 0,000171206 s, 0,0 kB/s
# dd if=/dev/urandom of=/test/512B bs=512 count=1
1+0
1+0
512 , 0,000215428 s, 2,4 MB/s
# dd if=/dev/urandom of=/test/513B bs=513 count=1
1+0
1+0
513 , 0,00022484 s, 2,3 MB/s
ファイルがディスク上でどれだけのスペースを占めるかを見てみましょう
# du -a --block-size=1
1024 ./512B
512 ./0B
2560 ./513B
顕著なのは、サイズ0のファイルが512バイトを占有することです(サイズが0バイトのext3と比較してください)。 サイズが513バイトのファイルは、1536バイトではなく2560バイトを占有しますが、recordizesizeの2倍のサイズとサービス情報に相当する場所が必要になります。 これが起こっている理由を見てみましょう。
アクティブなUberblockを見つける
生データにアクセスするには、radare2ユーティリティを使用します。
トランザクション番号で並べ替えます。
# r2 /tmp/test_disk
[0x00000000]> pf q @@s:0x20010 0x40000 0x400|sort -k2
0x00020010 = (qword)0x0000000000000000
…
0x00028010 = (qword)0x0000000000000020
0x00028810 = (qword)0x0000000000000022
0x00028c10 = (qword)0x0000000000000023
0x0002e010 = (qword)0x0000000000000038
アクティブなuberblockは0x0002e000にあります(見つかったオフセット0x0002e010から16バイトを減算します)。
uberblockを完全に読む
[0x0003fc10]> 0x0002e000
[0x0002e000]> pf qqqqt:[128].q ub_magic ub_version ub_txg ub_guid_sum ub_timestamp ub_software_version
ub_magic : 0x0002e000 = (qword)0x0000000000bab10c
ub_version : 0x0002e008 = (qword)0x0000000000001388
ub_txg : 0x0002e010 = (qword)0x0000000000000038
ub_guid_sum : 0x0002e018 = (qword)0x667c11fc34e97151
ub_timestamp : 0x0002e020 = Wed Jan 31 07:29:56 2018
ub_software_version : 0x0002e0a8 = (qword)0x0000000000001388
ub_rootbpを取得
[0x0002e000]> s+0x28
[0x0002e028]> pf [2]q[2]q[2]qq[2]qqqq[4]q blk_dva_0 blk_dva_1 blk_dva_2 blk_prop blk_pad[2] blk_phys_birth blk_birth blk_fill blk_cksum
blk_dva_0 : 0x0002e028 = (qword)[ 0x0000000000000001, 0x00000000000000ab ]
blk_dva_1 : 0x0002e038 = (qword)[ 0x0000000000000001, 0x00000000000000bc ]
blk_dva_2 : 0x0002e048 = (qword)[ 0x0000000000000001, 0x00000000000000bd ]
blk_prop : 0x0002e058 = (qword)0x800b070f00000003
blk_pad[2] : 0x0002e060 = (qword)[ 0x0000000000000000, 0x0000000000000000 ]
blk_phys_birth : 0x0002e070 = (qword)0x0000000000000000
blk_birth : 0x0002e078 = (qword)0x0000000000000038
blk_fill : 0x0002e080 = (qword)0x0000000000000023
blk_cksum : 0x0002e088 = (qword)[ 0x0000000d43174e30, 0x00000513bae6359f, 0x0000ff222817dfe3, 0x00223eedae162ece ]
blkptrパラメーター(blk_prop)を解析するには、MS Excellを使用します

comp(= 15)の値から判断すると、ブロックはlz4で圧縮され、ディスク上で512バイトを占有し(PSIZE-セクター数を示します)、解凍後は2048バイト(LSIZE)になります。
ブロックをファイルに保存する
ディスクの先頭からのオフセットを計算します。 これを行うには、blkptr構造体のblk_dva [0] .dva_word [1]フィールド(= 0x00000000000000ab)の値に512(セクターサイズ)を掛け、0x400000(4MB-ラベルL0、L1、ブートブロック)を追加します。 結果を512で割ります(各512バイトのブロックで作業します)。
[0x0002e028]> ?v 0x00000000000000ab<9+0x400000
0x415600
[0x0002e028]> ? 0x415600/512
8363 0x20ab 020253 8.2K 0000:00ab 8363 "\xab " 0b0010000010101011 8363.0 8363.000000f 8363.000000 0t102110202
# dd if=/tmp/test_disk bs=512 skip=8363 count=1 of=/tmp/mos.objset.bin.lz4
解凍には、小さなプログラムを使用します(記事の最後にあるソース)。
# zdec mos.objset.bin.lz4 mos.objset.bin 2048
Input: mos.objset.bin.lz4
Output: mos.objset.bin
Out size: 2048
-----------------------------
Input size: 512
Real input size: 187
Decompress result: 0
MOSオブジェクトに保存されているものを見てみましょう
# r2 mos.objset.bin
[0x00000000]> pf [512].[192].qq[304].[512].[512]. os_type os_flags
os_type : 0x000002c0 = (qword)0x0000000000000001
os_flags : 0x000002c8 = (qword)0x0000000000000000
[0x00000000]> pf bbbbbbbbww[4]bqq[4]q dn_type dn_indblkshift dn_nlevels dn_nblkptr dn_bonustype dn_checksum dn_compress dn_flags dn_datablkszsec dn_bonuslen dn_pad2[4] dn_maxblkid dn_used dn_pad3[4]
dn_type : 0x00000000 = 0x0a
dn_indblkshift : 0x00000001 = 0x0e
dn_nlevels : 0x00000002 = 0x01
dn_nblkptr : 0x00000003 = 0x03
dn_bonustype : 0x00000004 = 0x00
dn_checksum : 0x00000005 = 0x00
dn_compress : 0x00000006 = 0x00
dn_flags : 0x00000007 = 0x01
dn_datablkszsec : 0x00000008 = 0x0020
dn_bonuslen : 0x0000000a = 0x0000
dn_pad2[4] : 0x0000000c = [ 0x00, 0x00, 0x00, 0x00 ]
dn_maxblkid : 0x00000010 = (qword)0x0000000000000001
dn_used : 0x00000018 = (qword)0x0000000000001e00
dn_pad3[4] : 0x00000020 = (qword)[ 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000 ]
blkptr配列(オフセット+ 0x40の配列の先頭)を読み取ります。 Blkptr構造サイズ128バイト(オフセット+ 0x80)
[0x00000000]> s+0x40
[0x00000040]> pf [2]q[2]q[2]qq[2]qqqq[4]q blk_dva_0 blk_dva_1 blk_dva_2 blk_prop blk_pad[2] blk_phys_birth blk_birth blk_fill blk_cksum
blk_dva_0 : 0x00000040 = (qword)[ 0x0000000000000004, 0x00000000000000fd ]
blk_dva_1 : 0x00000050 = (qword)[ 0x0000000000000004, 0x0000000000000014 ]
blk_dva_2 : 0x00000060 = (qword)[ 0x0000000000000004, 0x0000000000000018 ]
blk_prop : 0x00000070 = (qword)0x800a070f0003001f
blk_pad[2] : 0x00000078 = (qword)[ 0x0000000000000000, 0x0000000000000000 ]
blk_phys_birth : 0x00000088 = (qword)0x0000000000000000
blk_birth : 0x00000090 = (qword)0x0000000000000038
blk_fill : 0x00000098 = (qword)0x000000000000001f
blk_cksum : 0x000000a0 = (qword)[ 0x0000005b728c5143, 0x00006add456a9057, 0x0046f84e9ebc9fc1, 0x227baf4ccb8d8253 ]
[0x00000040]> s+0x80
[0x000000c0]> pf [2]q[2]q[2]qq[2]qqqq[4]q blk_dva_0 blk_dva_1 blk_dva_2 blk_prop blk_pad[2] blk_phys_birth blk_birth blk_fill blk_cksum
blk_dva_0 : 0x000000c0 = (qword)[ 0x0000000000000001, 0x00000000000000c7 ]
blk_dva_1 : 0x000000d0 = (qword)[ 0x0000000000000001, 0x00000000000000c8 ]
blk_dva_2 : 0x000000e0 = (qword)[ 0x0000000000000001, 0x00000000000000f9 ]
blk_prop : 0x000000f0 = (qword)0x800a070f0000001f
blk_pad[2] : 0x000000f8 = (qword)[ 0x0000000000000000, 0x0000000000000000 ]
blk_phys_birth : 0x00000108 = (qword)0x0000000000000000
blk_birth : 0x00000110 = (qword)0x0000000000000038
blk_fill : 0x00000118 = (qword)0x0000000000000004
blk_cksum : 0x00000120 = (qword)[ 0x000000212e3f6320, 0x000007421d158d58, 0x00012cb9dd4a54c3, 0x0026ea30b4caddc5 ]
[0x000000c0]> s+0x80
[0x00000140]> pf [2]q[2]q[2]qq[2]qqqq[4]q blk_dva_0 blk_dva_1 blk_dva_2 blk_prop blk_pad[2] blk_phys_birth blk_birth blk_fill blk_cksum
blk_dva_0 : 0x00000140 = (qword)[ 0x0000000000000000, 0x0000000000000000 ]
blk_dva_1 : 0x00000150 = (qword)[ 0x0000000000000000, 0x0000000000000000 ]
blk_dva_2 : 0x00000160 = (qword)[ 0x0000000000000000, 0x0000000000000000 ]
blk_prop : 0x00000170 = (qword)0x0000000000000000
blk_pad[2] : 0x00000178 = (qword)[ 0x0000000000000000, 0x0000000000000000 ]
blk_phys_birth : 0x00000188 = (qword)0x0000000000000000
blk_birth : 0x00000190 = (qword)0x0000000000000000
blk_fill : 0x00000198 = (qword)0x0000000000000000
blk_cksum : 0x000001a0 = (qword)[ 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000 ]

ブロックはlz4アルゴリズムで圧縮されており、サイズはそれぞれ2048バイトと512バイトです(実際のサイズは16384バイトです)。
ファイルに保存して解凍する
# dd if=/tmp/test_disk bs=512 skip=8445 count=4 of=/tmp/dsl.dnode.0.bin.lz4
# dd if=/tmp/test_disk bs=512 skip=8391 count=1 of=/tmp/dsl.dnode.1.bin.lz4
# zdec dsl.dnode.0.bin.lz4 dsl.dnode.0.bin 16384
Input: dsl.dnode.0.bin.lz4
Output: dsl.dnode.0.bin
Out size: 16384
-----------------------------
Input size: 2048
Real input size: 1589
Decompress result: 0
# zdec dsl.dnode.1.bin.lz4 dsl.dnode.1.bin 16384
Input: dsl.dnode.1.bin.lz4
Output: dsl.dnode.1.bin
Out size: 16384
-----------------------------
Input size: 512
Real input size: 464
Decompress result: 0
オブジェクトのリストを作成する
31個のオブジェクト
# r2 dsl.dnode.0.bin
[0x00000000]> pf bbbbbbbbww[4]bqq[4]q dn_type dn_indblkshift dn_nlevels dn_nblkptr dn_bonustype dn_checksum dn_compress dn_flags dn_datablkszsec dn_bonuslen dn_pad2[4] dn_maxblkid dn_used dn_pad3[4]
dn_type : 0x00000000 = 0x00
dn_indblkshift : 0x00000001 = 0x00
dn_nlevels : 0x00000002 = 0x00
dn_nblkptr : 0x00000003 = 0x00
dn_bonustype : 0x00000004 = 0x00
dn_checksum : 0x00000005 = 0x00
dn_compress : 0x00000006 = 0x00
dn_flags : 0x00000007 = 0x00
dn_datablkszsec : 0x00000008 = 0x0000
dn_bonuslen : 0x0000000a = 0x0000
dn_pad2[4] : 0x0000000c = [ 0x00, 0x00, 0x00, 0x00 ]
dn_maxblkid : 0x00000010 = (qword)0x0000000000000000
dn_used : 0x00000018 = (qword)0x0000000000000000
dn_pad3[4] : 0x00000020 = (qword)[ 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000 ]
[0x00000000]> s+0x200
[0x00000200]> pf bbbbbbbbww[4]bqq[4]q dn_type dn_indblkshift dn_nlevels dn_nblkptr dn_bonustype dn_checksum dn_compress dn_flags dn_datablkszsec dn_bonuslen dn_pad2[4] dn_maxblkid dn_used dn_pad3[4]
dn_type : 0x00000200 = 0x01
dn_indblkshift : 0x00000201 = 0x0e
dn_nlevels : 0x00000202 = 0x01
dn_nblkptr : 0x00000203 = 0x03
dn_bonustype : 0x00000204 = 0x00
dn_checksum : 0x00000205 = 0x00
dn_compress : 0x00000206 = 0x00
dn_flags : 0x00000207 = 0x01
dn_datablkszsec : 0x00000208 = 0x0002
dn_bonuslen : 0x0000020a = 0x0000
dn_pad2[4] : 0x0000020c = [ 0x00, 0x00, 0x00, 0x00 ]
dn_maxblkid : 0x00000210 = (qword)0x0000000000000000
dn_used : 0x00000218 = (qword)0x0000000000000600
dn_pad3[4] : 0x00000220 = (qword)[ 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000 ]
[0x00000200]> s+0x200
[0x00000400]> pf bbbbbbbbww[4]bqq[4]q dn_type dn_indblkshift dn_nlevels dn_nblkptr dn_bonustype dn_checksum dn_compress dn_flags dn_datablkszsec dn_bonuslen dn_pad2[4] dn_maxblkid dn_used dn_pad3[4]
dn_type : 0x00000400 = 0x0c
dn_indblkshift : 0x00000401 = 0x0e
dn_nlevels : 0x00000402 = 0x01
dn_nblkptr : 0x00000403 = 0x01
dn_bonustype : 0x00000404 = 0x0c
dn_checksum : 0x00000405 = 0x00
dn_compress : 0x00000406 = 0x00
dn_flags : 0x00000407 = 0x00
dn_datablkszsec : 0x00000408 = 0x0001
dn_bonuslen : 0x0000040a = 0x0100
dn_pad2[4] : 0x0000040c = [ 0x00, 0x00, 0x00, 0x00 ]
dn_maxblkid : 0x00000410 = (qword)0x0000000000000000
dn_used : 0x00000418 = (qword)0x0000000000000000
dn_pad3[4] : 0x00000420 = (qword)[ 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000 ]
[0x00000400]> s+0x200
[0x00000600]> pf bbbbbbbbww[4]bqq[4]q dn_type dn_indblkshift dn_nlevels dn_nblkptr dn_bonustype dn_checksum dn_compress dn_flags dn_datablkszsec dn_bonuslen dn_pad2[4] dn_maxblkid dn_used dn_pad3[4]
dn_type : 0x00000600 = 0x0f
dn_indblkshift : 0x00000601 = 0x0e
dn_nlevels : 0x00000602 = 0x01
dn_nblkptr : 0x00000603 = 0x03
dn_bonustype : 0x00000604 = 0x00
dn_checksum : 0x00000605 = 0x00
dn_compress : 0x00000606 = 0x00
dn_flags : 0x00000607 = 0x01
dn_datablkszsec : 0x00000608 = 0x0001
dn_bonuslen : 0x0000060a = 0x0000
dn_pad2[4] : 0x0000060c = [ 0x00, 0x00, 0x00, 0x00 ]
dn_maxblkid : 0x00000610 = (qword)0x0000000000000000
dn_used : 0x00000618 = (qword)0x0000000000000000
dn_pad3[4] : 0x00000620 = (qword)[ 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000 ]
[0x00000600]> s+0x200
[0x00000800]> pf bbbbbbbbww[4]bqq[4]q dn_type dn_indblkshift dn_nlevels dn_nblkptr dn_bonustype dn_checksum dn_compress dn_flags dn_datablkszsec dn_bonuslen dn_pad2[4] dn_maxblkid dn_used dn_pad3[4]
dn_type : 0x00000800 = 0x0d
dn_indblkshift : 0x00000801 = 0x0e
dn_nlevels : 0x00000802 = 0x01
dn_nblkptr : 0x00000803 = 0x03
dn_bonustype : 0x00000804 = 0x00
dn_checksum : 0x00000805 = 0x00
dn_compress : 0x00000806 = 0x00
dn_flags : 0x00000807 = 0x01
dn_datablkszsec : 0x00000808 = 0x0001
dn_bonuslen : 0x0000080a = 0x0000
dn_pad2[4] : 0x0000080c = [ 0x00, 0x00, 0x00, 0x00 ]
dn_maxblkid : 0x00000810 = (qword)0x0000000000000000
dn_used : 0x00000818 = (qword)0x0000000000000000
dn_pad3[4] : 0x00000820 = (qword)[ 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000 ]
[0x00000800]> s+0x200
[0x00000a00]> pf bbbbbbbbww[4]bqq[4]q dn_type dn_indblkshift dn_nlevels dn_nblkptr dn_bonustype dn_checksum dn_compress dn_flags dn_datablkszsec dn_bonuslen dn_pad2[4] dn_maxblkid dn_used dn_pad3[4]
dn_type : 0x00000a00 = 0x0c
dn_indblkshift : 0x00000a01 = 0x0e
dn_nlevels : 0x00000a02 = 0x01
dn_nblkptr : 0x00000a03 = 0x01
dn_bonustype : 0x00000a04 = 0x0c
dn_checksum : 0x00000a05 = 0x00
dn_compress : 0x00000a06 = 0x00
dn_flags : 0x00000a07 = 0x00
dn_datablkszsec : 0x00000a08 = 0x0001
dn_bonuslen : 0x00000a0a = 0x0100
dn_pad2[4] : 0x00000a0c = [ 0x00, 0x00, 0x00, 0x00 ]
dn_maxblkid : 0x00000a10 = (qword)0x0000000000000000
dn_used : 0x00000a18 = (qword)0x0000000000000000
dn_pad3[4] : 0x00000a20 = (qword)[ 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000 ]
[0x00000a00]> s+0x200
[0x00000c00]> pf bbbbbbbbww[4]bqq[4]q dn_type dn_indblkshift dn_nlevels dn_nblkptr dn_bonustype dn_checksum dn_compress dn_flags dn_datablkszsec dn_bonuslen dn_pad2[4] dn_maxblkid dn_used dn_pad3[4]
dn_type : 0x00000c00 = 0x0f
dn_indblkshift : 0x00000c01 = 0x0e
dn_nlevels : 0x00000c02 = 0x01
dn_nblkptr : 0x00000c03 = 0x03
dn_bonustype : 0x00000c04 = 0x00
dn_checksum : 0x00000c05 = 0x00
dn_compress : 0x00000c06 = 0x00
dn_flags : 0x00000c07 = 0x01
dn_datablkszsec : 0x00000c08 = 0x0001
dn_bonuslen : 0x00000c0a = 0x0000
dn_pad2[4] : 0x00000c0c = [ 0x00, 0x00, 0x00, 0x00 ]
dn_maxblkid : 0x00000c10 = (qword)0x0000000000000000
dn_used : 0x00000c18 = (qword)0x0000000000000000
dn_pad3[4] : 0x00000c20 = (qword)[ 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000 ]
[0x00000c00]> s+0x200
[0x00000e00]> pf bbbbbbbbww[4]bqq[4]q dn_type dn_indblkshift dn_nlevels dn_nblkptr dn_bonustype dn_checksum dn_compress dn_flags dn_datablkszsec dn_bonuslen dn_pad2[4] dn_maxblkid dn_used dn_pad3[4]
dn_type : 0x00000e00 = 0x0d
dn_indblkshift : 0x00000e01 = 0x0e
dn_nlevels : 0x00000e02 = 0x01
dn_nblkptr : 0x00000e03 = 0x03
dn_bonustype : 0x00000e04 = 0x00
dn_checksum : 0x00000e05 = 0x00
dn_compress : 0x00000e06 = 0x00
dn_flags : 0x00000e07 = 0x01
dn_datablkszsec : 0x00000e08 = 0x0001
dn_bonuslen : 0x00000e0a = 0x0000
dn_pad2[4] : 0x00000e0c = [ 0x00, 0x00, 0x00, 0x00 ]
dn_maxblkid : 0x00000e10 = (qword)0x0000000000000000
dn_used : 0x00000e18 = (qword)0x0000000000000000
dn_pad3[4] : 0x00000e20 = (qword)[ 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000 ]
[0x00000e00]> s+0x200
[0x00001000]> pf bbbbbbbbww[4]bqq[4]q dn_type dn_indblkshift dn_nlevels dn_nblkptr dn_bonustype dn_checksum dn_compress dn_flags dn_datablkszsec dn_bonuslen dn_pad2[4] dn_maxblkid dn_used dn_pad3[4]
dn_type : 0x00001000 = 0x0c
dn_indblkshift : 0x00001001 = 0x0e
dn_nlevels : 0x00001002 = 0x01
dn_nblkptr : 0x00001003 = 0x01
dn_bonustype : 0x00001004 = 0x0c
dn_checksum : 0x00001005 = 0x00
dn_compress : 0x00001006 = 0x00
dn_flags : 0x00001007 = 0x00
dn_datablkszsec : 0x00001008 = 0x0001
dn_bonuslen : 0x0000100a = 0x0100
dn_pad2[4] : 0x0000100c = [ 0x00, 0x00, 0x00, 0x00 ]
dn_maxblkid : 0x00001010 = (qword)0x0000000000000000
dn_used : 0x00001018 = (qword)0x0000000000000000
dn_pad3[4] : 0x00001020 = (qword)[ 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000 ]
[0x00001000]> s+0x200
[0x00001200]> pf bbbbbbbbww[4]bqq[4]q dn_type dn_indblkshift dn_nlevels dn_nblkptr dn_bonustype dn_checksum dn_compress dn_flags dn_datablkszsec dn_bonuslen dn_pad2[4] dn_maxblkid dn_used dn_pad3[4]
dn_type : 0x00001200 = 0x0f
dn_indblkshift : 0x00001201 = 0x0e
dn_nlevels : 0x00001202 = 0x01
dn_nblkptr : 0x00001203 = 0x03
dn_bonustype : 0x00001204 = 0x00
dn_checksum : 0x00001205 = 0x00
dn_compress : 0x00001206 = 0x00
dn_flags : 0x00001207 = 0x01
dn_datablkszsec : 0x00001208 = 0x0001
dn_bonuslen : 0x0000120a = 0x0000
dn_pad2[4] : 0x0000120c = [ 0x00, 0x00, 0x00, 0x00 ]
dn_maxblkid : 0x00001210 = (qword)0x0000000000000000
dn_used : 0x00001218 = (qword)0x0000000000000000
dn_pad3[4] : 0x00001220 = (qword)[ 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000 ]
[0x00001200]> s+0x200
[0x00001400]> pf bbbbbbbbww[4]bqq[4]q dn_type dn_indblkshift dn_nlevels dn_nblkptr dn_bonustype dn_checksum dn_compress dn_flags dn_datablkszsec dn_bonuslen dn_pad2[4] dn_maxblkid dn_used dn_pad3[4]
dn_type : 0x00001400 = 0x0d
dn_indblkshift : 0x00001401 = 0x0e
dn_nlevels : 0x00001402 = 0x01
dn_nblkptr : 0x00001403 = 0x03
dn_bonustype : 0x00001404 = 0x00
dn_checksum : 0x00001405 = 0x00
dn_compress : 0x00001406 = 0x00
dn_flags : 0x00001407 = 0x01
dn_datablkszsec : 0x00001408 = 0x0001
dn_bonuslen : 0x0000140a = 0x0000
dn_pad2[4] : 0x0000140c = [ 0x00, 0x00, 0x00, 0x00 ]
dn_maxblkid : 0x00001410 = (qword)0x0000000000000000
dn_used : 0x00001418 = (qword)0x0000000000000000
dn_pad3[4] : 0x00001420 = (qword)[ 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000 ]
[0x00001400]> s+0x200
[0x00001600]> pf bbbbbbbbww[4]bqq[4]q dn_type dn_indblkshift dn_nlevels dn_nblkptr dn_bonustype dn_checksum dn_compress dn_flags dn_datablkszsec dn_bonuslen dn_pad2[4] dn_maxblkid dn_used dn_pad3[4]
dn_type : 0x00001600 = 0x05
dn_indblkshift : 0x00001601 = 0x0e
dn_nlevels : 0x00001602 = 0x01
dn_nblkptr : 0x00001603 = 0x03
dn_bonustype : 0x00001604 = 0x06
dn_checksum : 0x00001605 = 0x00
dn_compress : 0x00001606 = 0x00
dn_flags : 0x00001607 = 0x00
dn_datablkszsec : 0x00001608 = 0x0100
dn_bonuslen : 0x0000160a = 0x0030
dn_pad2[4] : 0x0000160c = [ 0x00, 0x00, 0x00, 0x00 ]
dn_maxblkid : 0x00001610 = (qword)0x0000000000000000
dn_used : 0x00001618 = (qword)0x0000000000000000
dn_pad3[4] : 0x00001620 = (qword)[ 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000 ]
[0x00001600]> s+0x200
[0x00001800]> pf bbbbbbbbww[4]bqq[4]q dn_type dn_indblkshift dn_nlevels dn_nblkptr dn_bonustype dn_checksum dn_compress dn_flags dn_datablkszsec dn_bonuslen dn_pad2[4] dn_maxblkid dn_used dn_pad3[4]
dn_type : 0x00001800 = 0x0c
dn_indblkshift : 0x00001801 = 0x0e
dn_nlevels : 0x00001802 = 0x01
dn_nblkptr : 0x00001803 = 0x01
dn_bonustype : 0x00001804 = 0x0c
dn_checksum : 0x00001805 = 0x00
dn_compress : 0x00001806 = 0x00
dn_flags : 0x00001807 = 0x00
dn_datablkszsec : 0x00001808 = 0x0001
dn_bonuslen : 0x0000180a = 0x0100
dn_pad2[4] : 0x0000180c = [ 0x00, 0x00, 0x00, 0x00 ]
dn_maxblkid : 0x00001810 = (qword)0x0000000000000000
dn_used : 0x00001818 = (qword)0x0000000000000000
dn_pad3[4] : 0x00001820 = (qword)[ 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000 ]
[0x00001800]> s+0x200
[0x00001a00]> pf bbbbbbbbww[4]bqq[4]q dn_type dn_indblkshift dn_nlevels dn_nblkptr dn_bonustype dn_checksum dn_compress dn_flags dn_datablkszsec dn_bonuslen dn_pad2[4] dn_maxblkid dn_used dn_pad3[4]
dn_type : 0x00001a00 = 0x0f
dn_indblkshift : 0x00001a01 = 0x0e
dn_nlevels : 0x00001a02 = 0x01
dn_nblkptr : 0x00001a03 = 0x03
dn_bonustype : 0x00001a04 = 0x00
dn_checksum : 0x00001a05 = 0x00
dn_compress : 0x00001a06 = 0x00
dn_flags : 0x00001a07 = 0x01
dn_datablkszsec : 0x00001a08 = 0x0001
dn_bonuslen : 0x00001a0a = 0x0000
dn_pad2[4] : 0x00001a0c = [ 0x00, 0x00, 0x00, 0x00 ]
dn_maxblkid : 0x00001a10 = (qword)0x0000000000000000
dn_used : 0x00001a18 = (qword)0x0000000000000000
dn_pad3[4] : 0x00001a20 = (qword)[ 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000 ]
[0x00001a00]> s+0x200
[0x00001c00]> pf bbbbbbbbww[4]bqq[4]q dn_type dn_indblkshift dn_nlevels dn_nblkptr dn_bonustype dn_checksum dn_compress dn_flags dn_datablkszsec dn_bonuslen dn_pad2[4] dn_maxblkid dn_used dn_pad3[4]
dn_type : 0x00001c00 = 0x0d
dn_indblkshift : 0x00001c01 = 0x0e
dn_nlevels : 0x00001c02 = 0x01
dn_nblkptr : 0x00001c03 = 0x03
dn_bonustype : 0x00001c04 = 0x00
dn_checksum : 0x00001c05 = 0x00
dn_compress : 0x00001c06 = 0x00
dn_flags : 0x00001c07 = 0x01
dn_datablkszsec : 0x00001c08 = 0x0001
dn_bonuslen : 0x00001c0a = 0x0000
dn_pad2[4] : 0x00001c0c = [ 0x00, 0x00, 0x00, 0x00 ]
dn_maxblkid : 0x00001c10 = (qword)0x0000000000000000
dn_used : 0x00001c18 = (qword)0x0000000000000000
dn_pad3[4] : 0x00001c20 = (qword)[ 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000 ]
[0x00001c00]> s+0x200
[0x00001e00]> pf bbbbbbbbww[4]bqq[4]q dn_type dn_indblkshift dn_nlevels dn_nblkptr dn_bonustype dn_checksum dn_compress dn_flags dn_datablkszsec dn_bonuslen dn_pad2[4] dn_maxblkid dn_used dn_pad3[4]
dn_type : 0x00001e00 = 0x10
dn_indblkshift : 0x00001e01 = 0x0e
dn_nlevels : 0x00001e02 = 0x01
dn_nblkptr : 0x00001e03 = 0x01
dn_bonustype : 0x00001e04 = 0x10
dn_checksum : 0x00001e05 = 0x00
dn_compress : 0x00001e06 = 0x00
dn_flags : 0x00001e07 = 0x00
dn_datablkszsec : 0x00001e08 = 0x0001
dn_bonuslen : 0x00001e0a = 0x0140
dn_pad2[4] : 0x00001e0c = [ 0x00, 0x00, 0x00, 0x00 ]
dn_maxblkid : 0x00001e10 = (qword)0x0000000000000000
dn_used : 0x00001e18 = (qword)0x0000000000000000
dn_pad3[4] : 0x00001e20 = (qword)[ 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000 ]
[0x00001e00]> s+0x200
[0x00002000]> pf bbbbbbbbww[4]bqq[4]q dn_type dn_indblkshift dn_nlevels dn_nblkptr dn_bonustype dn_checksum dn_compress dn_flags dn_datablkszsec dn_bonuslen dn_pad2[4] dn_maxblkid dn_used dn_pad3[4]
dn_type : 0x00002000 = 0x0e
dn_indblkshift : 0x00002001 = 0x0e
dn_nlevels : 0x00002002 = 0x01
dn_nblkptr : 0x00002003 = 0x03
dn_bonustype : 0x00002004 = 0x00
dn_checksum : 0x00002005 = 0x00
dn_compress : 0x00002006 = 0x00
dn_flags : 0x00002007 = 0x01
dn_datablkszsec : 0x00002008 = 0x0001
dn_bonuslen : 0x0000200a = 0x0000
dn_pad2[4] : 0x0000200c = [ 0x00, 0x00, 0x00, 0x00 ]
dn_maxblkid : 0x00002010 = (qword)0x0000000000000000
dn_used : 0x00002018 = (qword)0x0000000000000000
dn_pad3[4] : 0x00002020 = (qword)[ 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000 ]
[0x00002000]> s+0x200
[0x00002200]> pf bbbbbbbbww[4]bqq[4]q dn_type dn_indblkshift dn_nlevels dn_nblkptr dn_bonustype dn_checksum dn_compress dn_flags dn_datablkszsec dn_bonuslen dn_pad2[4] dn_maxblkid dn_used dn_pad3[4]
dn_type : 0x00002200 = 0x32
dn_indblkshift : 0x00002201 = 0x0e
dn_nlevels : 0x00002202 = 0x01
dn_nblkptr : 0x00002203 = 0x01
dn_bonustype : 0x00002204 = 0x33
dn_checksum : 0x00002205 = 0x00
dn_compress : 0x00002206 = 0x00
dn_flags : 0x00002207 = 0x01
dn_datablkszsec : 0x00002208 = 0x0001
dn_bonuslen : 0x0000220a = 0x0140
dn_pad2[4] : 0x0000220c = [ 0x00, 0x00, 0x00, 0x00 ]
dn_maxblkid : 0x00002210 = (qword)0x0000000000000000
dn_used : 0x00002218 = (qword)0x0000000000000000
dn_pad3[4] : 0x00002220 = (qword)[ 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000 ]
[0x00002200]> s+0x200
[0x00002400]> pf bbbbbbbbww[4]bqq[4]q dn_type dn_indblkshift dn_nlevels dn_nblkptr dn_bonustype dn_checksum dn_compress dn_flags dn_datablkszsec dn_bonuslen dn_pad2[4] dn_maxblkid dn_used dn_pad3[4]
dn_type : 0x00002400 = 0x10
dn_indblkshift : 0x00002401 = 0x0e
dn_nlevels : 0x00002402 = 0x01
dn_nblkptr : 0x00002403 = 0x01
dn_bonustype : 0x00002404 = 0x10
dn_checksum : 0x00002405 = 0x00
dn_compress : 0x00002406 = 0x00
dn_flags : 0x00002407 = 0x00
dn_datablkszsec : 0x00002408 = 0x0001
dn_bonuslen : 0x0000240a = 0x0140
dn_pad2[4] : 0x0000240c = [ 0x00, 0x00, 0x00, 0x00 ]
dn_maxblkid : 0x00002410 = (qword)0x0000000000000000
dn_used : 0x00002418 = (qword)0x0000000000000000
dn_pad3[4] : 0x00002420 = (qword)[ 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000 ]
[0x00002400]> s+0x200
[0x00002600]> pf bbbbbbbbww[4]bqq[4]q dn_type dn_indblkshift dn_nlevels dn_nblkptr dn_bonustype dn_checksum dn_compress dn_flags dn_datablkszsec dn_bonuslen dn_pad2[4] dn_maxblkid dn_used dn_pad3[4]
dn_type : 0x00002600 = 0x32
dn_indblkshift : 0x00002601 = 0x0e
dn_nlevels : 0x00002602 = 0x01
dn_nblkptr : 0x00002603 = 0x01
dn_bonustype : 0x00002604 = 0x33
dn_checksum : 0x00002605 = 0x00
dn_compress : 0x00002606 = 0x00
dn_flags : 0x00002607 = 0x01
dn_datablkszsec : 0x00002608 = 0x0001
dn_bonuslen : 0x0000260a = 0x0140
dn_pad2[4] : 0x0000260c = [ 0x00, 0x00, 0x00, 0x00 ]
dn_maxblkid : 0x00002610 = (qword)0x0000000000000000
dn_used : 0x00002618 = (qword)0x0000000000000000
dn_pad3[4] : 0x00002620 = (qword)[ 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000 ]
[0x00002600]> s+0x200
[0x00002800]> pf bbbbbbbbww[4]bqq[4]q dn_type dn_indblkshift dn_nlevels dn_nblkptr dn_bonustype dn_checksum dn_compress dn_flags dn_datablkszsec dn_bonuslen dn_pad2[4] dn_maxblkid dn_used dn_pad3[4]
dn_type : 0x00002800 = 0x05
dn_indblkshift : 0x00002801 = 0x0e
dn_nlevels : 0x00002802 = 0x01
dn_nblkptr : 0x00002803 = 0x03
dn_bonustype : 0x00002804 = 0x06
dn_checksum : 0x00002805 = 0x00
dn_compress : 0x00002806 = 0x00
dn_flags : 0x00002807 = 0x00
dn_datablkszsec : 0x00002808 = 0x0100
dn_bonuslen : 0x0000280a = 0x0030
dn_pad2[4] : 0x0000280c = [ 0x00, 0x00, 0x00, 0x00 ]
dn_maxblkid : 0x00002810 = (qword)0x0000000000000000
dn_used : 0x00002818 = (qword)0x0000000000000000
dn_pad3[4] : 0x00002820 = (qword)[ 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000 ]
[0x00002800]> s+0x200
[0x00002a00]> pf bbbbbbbbww[4]bqq[4]q dn_type dn_indblkshift dn_nlevels dn_nblkptr dn_bonustype dn_checksum dn_compress dn_flags dn_datablkszsec dn_bonuslen dn_pad2[4] dn_maxblkid dn_used dn_pad3[4]
dn_type : 0x00002a00 = 0x10
dn_indblkshift : 0x00002a01 = 0x0e
dn_nlevels : 0x00002a02 = 0x01
dn_nblkptr : 0x00002a03 = 0x01
dn_bonustype : 0x00002a04 = 0x10
dn_checksum : 0x00002a05 = 0x00
dn_compress : 0x00002a06 = 0x00
dn_flags : 0x00002a07 = 0x00
dn_datablkszsec : 0x00002a08 = 0x0001
dn_bonuslen : 0x00002a0a = 0x0140
dn_pad2[4] : 0x00002a0c = [ 0x00, 0x00, 0x00, 0x00 ]
dn_maxblkid : 0x00002a10 = (qword)0x0000000000000000
dn_used : 0x00002a18 = (qword)0x0000000000000000
dn_pad3[4] : 0x00002a20 = (qword)[ 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000 ]
[0x00002a00]> s+0x200
[0x00002c00]> pf bbbbbbbbww[4]bqq[4]q dn_type dn_indblkshift dn_nlevels dn_nblkptr dn_bonustype dn_checksum dn_compress dn_flags dn_datablkszsec dn_bonuslen dn_pad2[4] dn_maxblkid dn_used dn_pad3[4]
dn_type : 0x00002c00 = 0x0e
dn_indblkshift : 0x00002c01 = 0x0e
dn_nlevels : 0x00002c02 = 0x01
dn_nblkptr : 0x00002c03 = 0x03
dn_bonustype : 0x00002c04 = 0x00
dn_checksum : 0x00002c05 = 0x00
dn_compress : 0x00002c06 = 0x00
dn_flags : 0x00002c07 = 0x01
dn_datablkszsec : 0x00002c08 = 0x0001
dn_bonuslen : 0x00002c0a = 0x0000
dn_pad2[4] : 0x00002c0c = [ 0x00, 0x00, 0x00, 0x00 ]
dn_maxblkid : 0x00002c10 = (qword)0x0000000000000000
dn_used : 0x00002c18 = (qword)0x0000000000000000
dn_pad3[4] : 0x00002c20 = (qword)[ 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000 ]
[0x00002c00]> s+0x200
[0x00002e00]> pf bbbbbbbbww[4]bqq[4]q dn_type dn_indblkshift dn_nlevels dn_nblkptr dn_bonustype dn_checksum dn_compress dn_flags dn_datablkszsec dn_bonuslen dn_pad2[4] dn_maxblkid dn_used dn_pad3[4]
dn_type : 0x00002e00 = 0x32
dn_indblkshift : 0x00002e01 = 0x0e
dn_nlevels : 0x00002e02 = 0x01
dn_nblkptr : 0x00002e03 = 0x01
dn_bonustype : 0x00002e04 = 0x33
dn_checksum : 0x00002e05 = 0x00
dn_compress : 0x00002e06 = 0x00
dn_flags : 0x00002e07 = 0x01
dn_datablkszsec : 0x00002e08 = 0x0001
dn_bonuslen : 0x00002e0a = 0x0140
dn_pad2[4] : 0x00002e0c = [ 0x00, 0x00, 0x00, 0x00 ]
dn_maxblkid : 0x00002e10 = (qword)0x0000000000000000
dn_used : 0x00002e18 = (qword)0x0000000000000000
dn_pad3[4] : 0x00002e20 = (qword)[ 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000 ]
[0x00002e00]> s+0x200
[0x00003000]> pf bbbbbbbbww[4]bqq[4]q dn_type dn_indblkshift dn_nlevels dn_nblkptr dn_bonustype dn_checksum dn_compress dn_flags dn_datablkszsec dn_bonuslen dn_pad2[4] dn_maxblkid dn_used dn_pad3[4]
dn_type : 0x00003000 = 0x05
dn_indblkshift : 0x00003001 = 0x0e
dn_nlevels : 0x00003002 = 0x01
dn_nblkptr : 0x00003003 = 0x03
dn_bonustype : 0x00003004 = 0x06
dn_checksum : 0x00003005 = 0x00
dn_compress : 0x00003006 = 0x00
dn_flags : 0x00003007 = 0x00
dn_datablkszsec : 0x00003008 = 0x0100
dn_bonuslen : 0x0000300a = 0x0030
dn_pad2[4] : 0x0000300c = [ 0x00, 0x00, 0x00, 0x00 ]
dn_maxblkid : 0x00003010 = (qword)0x0000000000000000
dn_used : 0x00003018 = (qword)0x0000000000000000
dn_pad3[4] : 0x00003020 = (qword)[ 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000 ]
[0x00003000]> s+0x200
[0x00003200]> pf bbbbbbbbww[4]bqq[4]q dn_type dn_indblkshift dn_nlevels dn_nblkptr dn_bonustype dn_checksum dn_compress dn_flags dn_datablkszsec dn_bonuslen dn_pad2[4] dn_maxblkid dn_used dn_pad3[4]
dn_type : 0x00003200 = 0x25
dn_indblkshift : 0x00003201 = 0x0e
dn_nlevels : 0x00003202 = 0x01
dn_nblkptr : 0x00003203 = 0x03
dn_bonustype : 0x00003204 = 0x00
dn_checksum : 0x00003205 = 0x00
dn_compress : 0x00003206 = 0x00
dn_flags : 0x00003207 = 0x01
dn_datablkszsec : 0x00003208 = 0x0001
dn_bonuslen : 0x0000320a = 0x0000
dn_pad2[4] : 0x0000320c = [ 0x00, 0x00, 0x00, 0x00 ]
dn_maxblkid : 0x00003210 = (qword)0x0000000000000000
dn_used : 0x00003218 = (qword)0x0000000000000000
dn_pad3[4] : 0x00003220 = (qword)[ 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000 ]
[0x00003200]> s+0x200
[0x00003400]> pf bbbbbbbbww[4]bqq[4]q dn_type dn_indblkshift dn_nlevels dn_nblkptr dn_bonustype dn_checksum dn_compress dn_flags dn_datablkszsec dn_bonuslen dn_pad2[4] dn_maxblkid dn_used dn_pad3[4]
dn_type : 0x00003400 = 0x34
dn_indblkshift : 0x00003401 = 0x0e
dn_nlevels : 0x00003402 = 0x01
dn_nblkptr : 0x00003403 = 0x03
dn_bonustype : 0x00003404 = 0x00
dn_checksum : 0x00003405 = 0x00
dn_compress : 0x00003406 = 0x00
dn_flags : 0x00003407 = 0x01
dn_datablkszsec : 0x00003408 = 0x0001
dn_bonuslen : 0x0000340a = 0x0000
dn_pad2[4] : 0x0000340c = [ 0x00, 0x00, 0x00, 0x00 ]
dn_maxblkid : 0x00003410 = (qword)0x0000000000000000
dn_used : 0x00003418 = (qword)0x0000000000000000
dn_pad3[4] : 0x00003420 = (qword)[ 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000 ]
[0x00003400]> s+0x200
[0x00003600]> pf bbbbbbbbww[4]bqq[4]q dn_type dn_indblkshift dn_nlevels dn_nblkptr dn_bonustype dn_checksum dn_compress dn_flags dn_datablkszsec dn_bonuslen dn_pad2[4] dn_maxblkid dn_used dn_pad3[4]
dn_type : 0x00003600 = 0x03
dn_indblkshift : 0x00003601 = 0x0e
dn_nlevels : 0x00003602 = 0x01
dn_nblkptr : 0x00003603 = 0x03
dn_bonustype : 0x00003604 = 0x04
dn_checksum : 0x00003605 = 0x00
dn_compress : 0x00003606 = 0x00
dn_flags : 0x00003607 = 0x01
dn_datablkszsec : 0x00003608 = 0x0020
dn_bonuslen : 0x0000360a = 0x0008
dn_pad2[4] : 0x0000360c = [ 0x00, 0x00, 0x00, 0x00 ]
dn_maxblkid : 0x00003610 = (qword)0x0000000000000000
dn_used : 0x00003618 = (qword)0x0000000000000c00
dn_pad3[4] : 0x00003620 = (qword)[ 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000 ]
[0x00003600]> s+0x200
[0x00003800]> pf bbbbbbbbww[4]bqq[4]q dn_type dn_indblkshift dn_nlevels dn_nblkptr dn_bonustype dn_checksum dn_compress dn_flags dn_datablkszsec dn_bonuslen dn_pad2[4] dn_maxblkid dn_used dn_pad3[4]
dn_type : 0x00003800 = 0xc4
dn_indblkshift : 0x00003801 = 0x0e
dn_nlevels : 0x00003802 = 0x01
dn_nblkptr : 0x00003803 = 0x03
dn_bonustype : 0x00003804 = 0x00
dn_checksum : 0x00003805 = 0x00
dn_compress : 0x00003806 = 0x00
dn_flags : 0x00003807 = 0x01
dn_datablkszsec : 0x00003808 = 0x0001
dn_bonuslen : 0x0000380a = 0x0000
dn_pad2[4] : 0x0000380c = [ 0x00, 0x00, 0x00, 0x00 ]
dn_maxblkid : 0x00003810 = (qword)0x0000000000000000
dn_used : 0x00003818 = (qword)0x0000000000000600
dn_pad3[4] : 0x00003820 = (qword)[ 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000 ]
[0x00003800]> s+0x200
[0x00003a00]> pf bbbbbbbbww[4]bqq[4]q dn_type dn_indblkshift dn_nlevels dn_nblkptr dn_bonustype dn_checksum dn_compress dn_flags dn_datablkszsec dn_bonuslen dn_pad2[4] dn_maxblkid dn_used dn_pad3[4]
dn_type : 0x00003a00 = 0xc4
dn_indblkshift : 0x00003a01 = 0x0e
dn_nlevels : 0x00003a02 = 0x01
dn_nblkptr : 0x00003a03 = 0x03
dn_bonustype : 0x00003a04 = 0x00
dn_checksum : 0x00003a05 = 0x00
dn_compress : 0x00003a06 = 0x00
dn_flags : 0x00003a07 = 0x01
dn_datablkszsec : 0x00003a08 = 0x0001
dn_bonuslen : 0x00003a0a = 0x0000
dn_pad2[4] : 0x00003a0c = [ 0x00, 0x00, 0x00, 0x00 ]
dn_maxblkid : 0x00003a10 = (qword)0x0000000000000000
dn_used : 0x00003a18 = (qword)0x0000000000000600
dn_pad3[4] : 0x00003a20 = (qword)[ 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000 ]
[0x00003a00]> s+0x200
[0x00003c00]> pf bbbbbbbbww[4]bqq[4]q dn_type dn_indblkshift dn_nlevels dn_nblkptr dn_bonustype dn_checksum dn_compress dn_flags dn_datablkszsec dn_bonuslen dn_pad2[4] dn_maxblkid dn_used dn_pad3[4]
dn_type : 0x00003c00 = 0xc4
dn_indblkshift : 0x00003c01 = 0x0e
dn_nlevels : 0x00003c02 = 0x01
dn_nblkptr : 0x00003c03 = 0x03
dn_bonustype : 0x00003c04 = 0x00
dn_checksum : 0x00003c05 = 0x00
dn_compress : 0x00003c06 = 0x00
dn_flags : 0x00003c07 = 0x01
dn_datablkszsec : 0x00003c08 = 0x0020
dn_bonuslen : 0x00003c0a = 0x0000
dn_pad2[4] : 0x00003c0c = [ 0x00, 0x00, 0x00, 0x00 ]
dn_maxblkid : 0x00003c10 = (qword)0x0000000000000001
dn_used : 0x00003c18 = (qword)0x0000000000003600
dn_pad3[4] : 0x00003c20 = (qword)[ 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000 ]
[0x00003c00]> s+0x200
[0x00003e00]> pf bbbbbbbbww[4]bqq[4]q dn_type dn_indblkshift dn_nlevels dn_nblkptr dn_bonustype dn_checksum dn_compress dn_flags dn_datablkszsec dn_bonuslen dn_pad2[4] dn_maxblkid dn_used dn_pad3[4]
dn_type : 0x00003e00 = 0x05
dn_indblkshift : 0x00003e01 = 0x0e
dn_nlevels : 0x00003e02 = 0x01
dn_nblkptr : 0x00003e03 = 0x03
dn_bonustype : 0x00003e04 = 0x06
dn_checksum : 0x00003e05 = 0x00
dn_compress : 0x00003e06 = 0x02
dn_flags : 0x00003e07 = 0x01
dn_datablkszsec : 0x00003e08 = 0x0020
dn_bonuslen : 0x00003e0a = 0x0030
dn_pad2[4] : 0x00003e0c = [ 0x00, 0x00, 0x00, 0x00 ]
dn_maxblkid : 0x00003e10 = (qword)0x0000000000000000
dn_used : 0x00003e18 = (qword)0x0000000000000600
dn_pad3[4] : 0x00003e20 = (qword)[ 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000 ]
4つのオブジェクト
# r2 dsl.dnode.1.bin
[0x00000000]> pf bbbbbbbbww[4]bqq[4]q dn_type dn_indblkshift dn_nlevels dn_nblkptr dn_bonustype dn_checksum dn_compress dn_flags dn_datablkszsec dn_bonuslen dn_pad2[4] dn_maxblkid dn_used dn_pad3[4]
dn_type : 0x00000000 = 0x1d
dn_indblkshift : 0x00000001 = 0x0e
dn_nlevels : 0x00000002 = 0x01
dn_nblkptr : 0x00000003 = 0x03
dn_bonustype : 0x00000004 = 0x1e
dn_checksum : 0x00000005 = 0x00
dn_compress : 0x00000006 = 0x00
dn_flags : 0x00000007 = 0x01
dn_datablkszsec : 0x00000008 = 0x0100
dn_bonuslen : 0x0000000a = 0x0028
dn_pad2[4] : 0x0000000c = [ 0x00, 0x00, 0x00, 0x00 ]
dn_maxblkid : 0x00000010 = (qword)0x0000000000000000
dn_used : 0x00000018 = (qword)0x0000000000001200
dn_pad3[4] : 0x00000020 = (qword)[ 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000 ]
[0x00000000]> s+0x200
[0x00000200]> pf bbbbbbbbww[4]bqq[4]q dn_type dn_indblkshift dn_nlevels dn_nblkptr dn_bonustype dn_checksum dn_compress dn_flags dn_datablkszsec dn_bonuslen dn_pad2[4] dn_maxblkid dn_used dn_pad3[4]
dn_type : 0x00000200 = 0xc4
dn_indblkshift : 0x00000201 = 0x0e
dn_nlevels : 0x00000202 = 0x01
dn_nblkptr : 0x00000203 = 0x03
dn_bonustype : 0x00000204 = 0x00
dn_checksum : 0x00000205 = 0x00
dn_compress : 0x00000206 = 0x00
dn_flags : 0x00000207 = 0x01
dn_datablkszsec : 0x00000208 = 0x0001
dn_bonuslen : 0x0000020a = 0x0000
dn_pad2[4] : 0x0000020c = [ 0x00, 0x00, 0x00, 0x00 ]
dn_maxblkid : 0x00000210 = (qword)0x0000000000000000
dn_used : 0x00000218 = (qword)0x0000000000000600
dn_pad3[4] : 0x00000220 = (qword)[ 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000 ]
[0x00000200]> s+0x200
[0x00000400]> pf bbbbbbbbww[4]bqq[4]q dn_type dn_indblkshift dn_nlevels dn_nblkptr dn_bonustype dn_checksum dn_compress dn_flags dn_datablkszsec dn_bonuslen dn_pad2[4] dn_maxblkid dn_used dn_pad3[4]
dn_type : 0x00000400 = 0x02
dn_indblkshift : 0x00000401 = 0x0e
dn_nlevels : 0x00000402 = 0x01
dn_nblkptr : 0x00000403 = 0x03
dn_bonustype : 0x00000404 = 0x00
dn_checksum : 0x00000405 = 0x00
dn_compress : 0x00000406 = 0x00
dn_flags : 0x00000407 = 0x01
dn_datablkszsec : 0x00000408 = 0x0001
dn_bonuslen : 0x0000040a = 0x0000
dn_pad2[4] : 0x0000040c = [ 0x00, 0x00, 0x00, 0x00 ]
dn_maxblkid : 0x00000410 = (qword)0x0000000000000000
dn_used : 0x00000418 = (qword)0x0000000000000000
dn_pad3[4] : 0x00000420 = (qword)[ 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000 ]
[0x00000400]> s+0x200
[0x00000600]> pf bbbbbbbbww[4]bqq[4]q dn_type dn_indblkshift dn_nlevels dn_nblkptr dn_bonustype dn_checksum dn_compress dn_flags dn_datablkszsec dn_bonuslen dn_pad2[4] dn_maxblkid dn_used dn_pad3[4]
dn_type : 0x00000600 = 0x08
dn_indblkshift : 0x00000601 = 0x0e
dn_nlevels : 0x00000602 = 0x01
dn_nblkptr : 0x00000603 = 0x01
dn_bonustype : 0x00000604 = 0x07
dn_checksum : 0x00000605 = 0x00
dn_compress : 0x00000606 = 0x00
dn_flags : 0x00000607 = 0x01
dn_datablkszsec : 0x00000608 = 0x0008
dn_bonuslen : 0x0000060a = 0x0140
dn_pad2[4] : 0x0000060c = [ 0x00, 0x00, 0x00, 0x00 ]
dn_maxblkid : 0x00000610 = (qword)0x0000000000000000
dn_used : 0x00000618 = (qword)0x0000000000000c00
dn_pad3[4] : 0x00000620 = (qword)[ 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000 ]
現時点では、オブジェクト15、18、21に関心があります。
インデックス | dn_type | dn_bonustype | dn_bonuslen | ||
15 | 0x10 | DMU_OT_DSL_DATASET | 0x10 | DMU_OT_DSL_DATASET | 0x0140 |
18 | 0x10 | DMU_OT_DSL_DATASET | 0x10 | DMU_OT_DSL_DATASET | 0x0140 |
21 | 0x10 | DMU_OT_DSL_DATASET | 0x10 | DMU_OT_DSL_DATASET | 0x0140 |
タイプDMU_OT_DSL_DATASETのオブジェクトの場合、dsl_dataset_phys構造はdnode構造のボーナスバッファーに格納されます。
typedef struct dsl_dataset_phys { uint64_t ds_dir_obj; /* DMU_OT_DSL_DIR */ uint64_t ds_prev_snap_obj; /* DMU_OT_DSL_DATASET */ uint64_t ds_prev_snap_txg; uint64_t ds_next_snap_obj; /* DMU_OT_DSL_DATASET */ uint64_t ds_snapnames_zapobj; /* DMU_OT_DSL_DS_SNAP_MAP 0 for snaps */ uint64_t ds_num_children; /* clone/snap children; ==0 for head */ uint64_t ds_creation_time; /* seconds since 1970 */ uint64_t ds_creation_txg; uint64_t ds_deadlist_obj; /* DMU_OT_DEADLIST */ /* * ds_referenced_bytes, ds_compressed_bytes, and ds_uncompressed_bytes * include all blocks referenced by this dataset, including those * shared with any other datasets. */ uint64_t ds_referenced_bytes; uint64_t ds_compressed_bytes; uint64_t ds_uncompressed_bytes; uint64_t ds_unique_bytes; /* only relevant to snapshots */ /* * The ds_fsid_guid is a 56-bit ID that can change to avoid * collisions. The ds_guid is a 64-bit ID that will never * change, so there is a small probability that it will collide. */ uint64_t ds_fsid_guid; uint64_t ds_guid; uint64_t ds_flags; /* DS_FLAG_* */ blkptr_t ds_bp; uint64_t ds_next_clones_obj; /* DMU_OT_DSL_CLONES */ uint64_t ds_props_obj; /* DMU_OT_DSL_PROPS for snaps */ uint64_t ds_userrefs_obj; /* DMU_OT_USERREFS */ uint64_t ds_pad[5]; /* pad out to 320 bytes for good measure */ } dsl_dataset_phys_t;
オブジェクトの読み取り15
# r2 dsl.dnode.0.bin
-- Change the size of the file with the 'r' (resize) command
[0x00000000]> 0x00001e00
[0x00001e00]> s+0x40
[0x00001e40]> s+0x80
[0x00001ec0]> pf qqqqqqt:qqqqqqqqqb[127].qqq[5]q ds_dir_obj ds_prev_snap_obj ds_prev_snap_txg ds_next_snap_obj ds_snapnames_zapobj ds_num_children ds_creation_time ds_creation_txg ds_deadlist_obj ds_referenced_bytes ds_compressed_bytes ds_uncompressed_bytes ds_unique_bytes ds_fsid_guid ds_guid ds_flags ds_bp ds_next_clones_obj ds_props_obj ds_userrefs_obj ds_pad[5]
ds_dir_obj : 0x00001ec0 = (qword)0x000000000000000c
ds_prev_snap_obj : 0x00001ec8 = (qword)0x0000000000000012
ds_prev_snap_txg : 0x00001ed0 = (qword)0x0000000000000001
ds_next_snap_obj : 0x00001ed8 = (qword)0x0000000000000000
ds_snapnames_zapobj : 0x00001ee0 = (qword)0x0000000000000010
ds_num_children : 0x00001ee8 = (qword)0x0000000000000000
ds_creation_time : 0x00001ef0 = Wed Jan 31 07:25:31 2018
ds_creation_txg : 0x00001ef8 = (qword)0x0000000000000001
ds_deadlist_obj : 0x00001f00 = (qword)0x0000000000000013
ds_referenced_bytes : 0x00001f08 = (qword)0x0000000000000000
ds_compressed_bytes : 0x00001f10 = (qword)0x0000000000000000
ds_uncompressed_bytes : 0x00001f18 = (qword)0x0000000000000000
ds_unique_bytes : 0x00001f20 = (qword)0x0000000000000000
ds_fsid_guid : 0x00001f28 = (qword)0x0072595fd26fec77
ds_guid : 0x00001f30 = (qword)0x3723b59bcad0d186
ds_flags : 0x00001f38 = (qword)0x0000000000000004
ds_bp : 0x00001f40 = 0x00
ds_next_clones_obj : 0x00001fc0 = (qword)0x0000000000000000
ds_props_obj : 0x00001fc8 = (qword)0x0000000000000000
ds_userrefs_obj : 0x00001fd0 = (qword)0x0000000000000000
ds_pad[5] : 0x00001fd8 = (qword)[ 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000 ]
0x00001f40
[0x00001f40]> pf [2]q[2]q[2]qq[2]qqqq[4]q blk_dva_0 blk_dva_1 blk_dva_2 blk_prop blk_pad[2] blk_phys_birth blk_birth blk_fill blk_cksum
blk_dva_0 : 0x00001f40 = (qword)[ 0x0000000000000000, 0x0000000000000000 ]
blk_dva_1 : 0x00001f50 = (qword)[ 0x0000000000000000, 0x0000000000000000 ]
blk_dva_2 : 0x00001f60 = (qword)[ 0x0000000000000000, 0x0000000000000000 ]
blk_prop : 0x00001f70 = (qword)0x0000000000000000
blk_pad[2] : 0x00001f78 = (qword)[ 0x0000000000000000, 0x0000000000000000 ]
blk_phys_birth : 0x00001f88 = (qword)0x0000000000000000
blk_birth : 0x00001f90 = (qword)0x0000000000000000
blk_fill : 0x00001f98 = (qword)0x0000000000000000
blk_cksum : 0x00001fa0 = (qword)[ 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000 ]
オブジェクトの読み取り18
0x00002400
[0x00002400]> s+0x40
[0x00002440]> s+0x80
[0x000024c0]> pf qqqqqqt:qqqqqqqqqb[127].qqq[5]q ds_dir_obj ds_prev_snap_obj ds_prev_snap_txg ds_next_snap_obj ds_snapnames_zapobj ds_num_children ds_creation_time ds_creation_txg ds_deadlist_obj ds_referenced_bytes ds_compressed_bytes ds_uncompressed_bytes ds_unique_bytes ds_fsid_guid ds_guid ds_flags ds_bp ds_next_clones_obj ds_props_obj ds_userrefs_obj ds_pad[5]
ds_dir_obj : 0x000024c0 = (qword)0x000000000000000c
ds_prev_snap_obj : 0x000024c8 = (qword)0x0000000000000000
ds_prev_snap_txg : 0x000024d0 = (qword)0x0000000000000000
ds_next_snap_obj : 0x000024d8 = (qword)0x000000000000000f
ds_snapnames_zapobj : 0x000024e0 = (qword)0x0000000000000000
ds_num_children : 0x000024e8 = (qword)0x0000000000000002
ds_creation_time : 0x000024f0 = Wed Jan 31 07:25:31 2018
ds_creation_txg : 0x000024f8 = (qword)0x0000000000000001
ds_deadlist_obj : 0x00002500 = (qword)0x0000000000000011
ds_referenced_bytes : 0x00002508 = (qword)0x0000000000000000
ds_compressed_bytes : 0x00002510 = (qword)0x0000000000000000
ds_uncompressed_bytes : 0x00002518 = (qword)0x0000000000000000
ds_unique_bytes : 0x00002520 = (qword)0x0000000000000000
ds_fsid_guid : 0x00002528 = (qword)0x007551fa166ccbaf
ds_guid : 0x00002530 = (qword)0x107a852b04f9f01f
ds_flags : 0x00002538 = (qword)0x0000000000000004
ds_bp : 0x00002540 = 0x00
ds_next_clones_obj : 0x000025c0 = (qword)0x0000000000000019
ds_props_obj : 0x000025c8 = (qword)0x0000000000000000
ds_userrefs_obj : 0x000025d0 = (qword)0x0000000000000000
ds_pad[5] : 0x000025d8 = (qword)[ 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000 ]
0x00002540
[0x00002540]> pf [2]q[2]q[2]qq[2]qqqq[4]q blk_dva_0 blk_dva_1 blk_dva_2 blk_prop blk_pad[2] blk_phys_birth blk_birth blk_fill blk_cksum
blk_dva_0 : 0x00002540 = (qword)[ 0x0000000000000000, 0x0000000000000000 ]
blk_dva_1 : 0x00002550 = (qword)[ 0x0000000000000000, 0x0000000000000000 ]
blk_dva_2 : 0x00002560 = (qword)[ 0x0000000000000000, 0x0000000000000000 ]
blk_prop : 0x00002570 = (qword)0x0000000000000000
blk_pad[2] : 0x00002578 = (qword)[ 0x0000000000000000, 0x0000000000000000 ]
blk_phys_birth : 0x00002588 = (qword)0x0000000000000000
blk_birth : 0x00002590 = (qword)0x0000000000000000
blk_fill : 0x00002598 = (qword)0x0000000000000000
blk_cksum : 0x000025a0 = (qword)[ 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000 ]
オブジェクト21の読み取り
0x00002a00
[0x00002a00]> s+0x40
[0x00002a40]> s+0x80
[0x00002ac0]> pf qqqqqqt:qqqqqqqqqb[127].qqq[5]q ds_dir_obj ds_prev_snap_obj ds_prev_snap_txg ds_next_snap_obj ds_snapnames_zapobj ds_num_children ds_creation_time ds_creation_txg ds_deadlist_obj ds_referenced_bytes ds_compressed_bytes ds_uncompressed_bytes ds_unique_bytes ds_fsid_guid ds_guid ds_flags ds_bp ds_next_clones_obj ds_props_obj ds_userrefs_obj ds_pad[5]
ds_dir_obj : 0x00002ac0 = (qword)0x0000000000000002
ds_prev_snap_obj : 0x00002ac8 = (qword)0x0000000000000012
ds_prev_snap_txg : 0x00002ad0 = (qword)0x0000000000000001
ds_next_snap_obj : 0x00002ad8 = (qword)0x0000000000000000
ds_snapnames_zapobj : 0x00002ae0 = (qword)0x0000000000000016
ds_num_children : 0x00002ae8 = (qword)0x0000000000000000
ds_creation_time : 0x00002af0 = Wed Jan 31 07:25:31 2018
ds_creation_txg : 0x00002af8 = (qword)0x0000000000000001
ds_deadlist_obj : 0x00002b00 = (qword)0x0000000000000017
ds_referenced_bytes : 0x00002b08 = (qword)0x0000000000005600
ds_compressed_bytes : 0x00002b10 = (qword)0x0000000000002e00
ds_uncompressed_bytes : 0x00002b18 = (qword)0x0000000000002e00
ds_unique_bytes : 0x00002b20 = (qword)0x0000000000005600
ds_fsid_guid : 0x00002b28 = (qword)0x00aca2eec566a5b9
ds_guid : 0x00002b30 = (qword)0x6994c8e8b2452f06
ds_flags : 0x00002b38 = (qword)0x0000000000000004
ds_bp : 0x00002b40 = 0x01
ds_next_clones_obj : 0x00002bc0 = (qword)0x0000000000000000
ds_props_obj : 0x00002bc8 = (qword)0x0000000000000000
ds_userrefs_obj : 0x00002bd0 = (qword)0x0000000000000000
ds_pad[5] : 0x00002bd8 = (qword)[ 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000 ]
0x00002b40
[0x00002b40]> pf [2]q[2]q[2]qq[2]qqqq[4]q blk_dva_0 blk_dva_1 blk_dva_2 blk_prop blk_pad[2] blk_phys_birth blk_birth blk_fill blk_cksum
blk_dva_0 : 0x00002b40 = (qword)[ 0x0000000000000001, 0x0000000000000057 ]
blk_dva_1 : 0x00002b50 = (qword)[ 0x0000000000000001, 0x0000000000000058 ]
blk_dva_2 : 0x00002b60 = (qword)[ 0x0000000000000000, 0x0000000000000000 ]
blk_prop : 0x00002b70 = (qword)0x800b070f00000003
blk_pad[2] : 0x00002b78 = (qword)[ 0x0000000000000000, 0x0000000000000000 ]
blk_phys_birth : 0x00002b88 = (qword)0x0000000000000000
blk_birth : 0x00002b90 = (qword)0x0000000000000038
blk_fill : 0x00002b98 = (qword)0x0000000000000009
blk_cksum : 0x00002ba0 = (qword)[ 0x0000000efd4a0466, 0x000005ded369f382, 0x00012e169b3aebd5, 0x00298598c4f3c9d9 ]

このオブジェクトのみがデータを保存し、それから作業します。
ファイルに保存して解凍する
# dd if=/tmp/test_disk bs=512 skip=8279 count=1 of=/tmp/os.dataset.bin.lz4
# zdec os.dataset.bin.lz4 os.dataset.bin 2048
Input: os.dataset.bin.lz4
Output: os.dataset.bin
Out size: 2048
-----------------------------
Input size: 512
Real input size: 201
Decompress result: 0
objsetの内容を見る
# r2 os.dataset.bin
[0x00000000]> pf [512].[192].qq[304].[512].[512]. os_type os_flags
os_type : 0x000002c0 = (qword)0x0000000000000002
os_flags : 0x000002c8 = (qword)0x0000000000000001
[0x00000000]> pf bbbbbbbbww[4]bqq[4]q dn_type dn_indblkshift dn_nlevels dn_nblkptr dn_bonustype dn_checksum dn_compress dn_flags dn_datablkszsec dn_bonuslen dn_pad2[4] dn_maxblkid dn_used dn_pad3[4]
dn_type : 0x00000000 = 0x0a
dn_indblkshift : 0x00000001 = 0x0e
dn_nlevels : 0x00000002 = 0x07
dn_nblkptr : 0x00000003 = 0x03
dn_bonustype : 0x00000004 = 0x00
dn_checksum : 0x00000005 = 0x00
dn_compress : 0x00000006 = 0x00
dn_flags : 0x00000007 = 0x01
dn_datablkszsec : 0x00000008 = 0x0020
dn_bonuslen : 0x0000000a = 0x0000
dn_pad2[4] : 0x0000000c = [ 0x00, 0x00, 0x00, 0x00 ]
dn_maxblkid : 0x00000010 = (qword)0x0000000000000000
dn_used : 0x00000018 = (qword)0x0000000000002000
dn_pad3[4] : 0x00000020 = (qword)[ 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000 ]
[0x00000000]> s+0x40
[0x00000040]> pf [2]q[2]q[2]qq[2]qqqq[4]q blk_dva_0 blk_dva_1 blk_dva_2 blk_prop blk_pad[2] blk_phys_birth blk_birth blk_fill blk_cksum
blk_dva_0 : 0x00000040 = (qword)[ 0x0000000000000001, 0x000000000000010c ]
blk_dva_1 : 0x00000050 = (qword)[ 0x0000000000000001, 0x000000000000010d ]
blk_dva_2 : 0x00000060 = (qword)[ 0x0000000000000000, 0x0000000000000000 ]
blk_prop : 0x00000070 = (qword)0x860a070f0000001f
blk_pad[2] : 0x00000078 = (qword)[ 0x0000000000000000, 0x0000000000000000 ]
blk_phys_birth : 0x00000088 = (qword)0x0000000000000000
blk_birth : 0x00000090 = (qword)0x0000000000000038
blk_fill : 0x00000098 = (qword)0x0000000000000009
blk_cksum : 0x000000a0 = (qword)[ 0x0000001353eb3bd1, 0x000007c5fce654db, 0x000196a4bd5ee712, 0x00384d0db7501d91 ]

これはレベル6の間接ブロックへのリンクであり、レベル0まで順番に掘ります。
L6
# dd if=/tmp/test_disk bs=512 skip=8460 count=1 of=/tmp/os.dataset.dnode.l6.bin.lz4
# zdec os.dataset.dnode.l6.bin.lz4 os.dataset.dnode.l6.bin 16384
Input: os.dataset.dnode.l6.bin.lz4
Output: os.dataset.dnode.l6.bin
Out size: 16384
-----------------------------
Input size: 512
Real input size: 150
Decompress result: 0
# r2 os.dataset.dnode.l6.bin
[0x00000000]> pf [2]q[2]q[2]qq[2]qqqq[4]q blk_dva_0 blk_dva_1 blk_dva_2 blk_prop blk_pad[2] blk_phys_birth blk_birth blk_fill blk_cksum
blk_dva_0 : 0x00000000 = (qword)[ 0x0000000000000001, 0x00000000000000b6 ]
blk_dva_1 : 0x00000010 = (qword)[ 0x0000000000000001, 0x000000000000010b ]
blk_dva_2 : 0x00000020 = (qword)[ 0x0000000000000000, 0x0000000000000000 ]
blk_prop : 0x00000030 = (qword)0x850a070f0000001f
blk_pad[2] : 0x00000038 = (qword)[ 0x0000000000000000, 0x0000000000000000 ]
blk_phys_birth : 0x00000048 = (qword)0x0000000000000000
blk_birth : 0x00000050 = (qword)0x0000000000000038
blk_fill : 0x00000058 = (qword)0x0000000000000009
blk_cksum : 0x00000060 = (qword)[ 0x00000012eaa1fd11, 0x000007989478980e, 0x00018c88e386c191, 0x0036c2a7102bf2c2 ]
L5
[0x00000000]> "? 0x400000/512 + 0x00000000000000b6"
8374 0x20b6 020266 8.2K 0000:00b6 8374 "\xb6 " 0b0010000010110110 8374.0 8374.000000f 8374.000000 0t102111011
# dd if=/tmp/test_disk bs=512 skip=8374 count=1 of=/tmp/os.dataset.dnode.l5.bin.lz4
# zdec os.dataset.dnode.l5.bin.lz4 os.dataset.dnode.l5.bin 16384
Input: os.dataset.dnode.l5.bin.lz4
Output: os.dataset.dnode.l5.bin
Out size: 16384
-----------------------------
Input size: 512
Real input size: 149
Decompress result: 0
# r2 os.dataset.dnode.l5.bin
[0x00000000]> pf [2]q[2]q[2]qq[2]qqqq[4]q blk_dva_0 blk_dva_1 blk_dva_2 blk_prop blk_pad[2] blk_phys_birth blk_birth blk_fill blk_cksum
blk_dva_0 : 0x00000000 = (qword)[ 0x0000000000000001, 0x00000000000000b4 ]
blk_dva_1 : 0x00000010 = (qword)[ 0x0000000000000001, 0x00000000000000b5 ]
blk_dva_2 : 0x00000020 = (qword)[ 0x0000000000000000, 0x0000000000000000 ]
blk_prop : 0x00000030 = (qword)0x840a070f0000001f
blk_pad[2] : 0x00000038 = (qword)[ 0x0000000000000000, 0x0000000000000000 ]
blk_phys_birth : 0x00000048 = (qword)0x0000000000000000
blk_birth : 0x00000050 = (qword)0x0000000000000038
blk_fill : 0x00000058 = (qword)0x0000000000000009
blk_cksum : 0x00000060 = (qword)[ 0x000000135bd403fd, 0x000007c79b2ed6a0, 0x0001969b589bf00e, 0x00383d2f2da4c77e ]
L4
[0x00000000]> "? 0x400000/512 + 0x00000000000000b4"
8372 0x20b4 020264 8.2K 0000:00b4 8372 "\xb4 " 0b0010000010110100 8372.0 8372.000000f 8372.000000 0t102111002
# dd if=/tmp/test_disk bs=512 skip=8372 count=1 of=/tmp/os.dataset.dnode.l4.bin.lz4
# zdec os.dataset.dnode.l4.bin.lz4 os.dataset.dnode.l4.bin 16384
Input: os.dataset.dnode.l4.bin.lz4
Output: os.dataset.dnode.l4.bin
Out size: 16384
-----------------------------
Input size: 512
Real input size: 150
Decompress result: 0
# r2 os.dataset.dnode.l4.bin
-- Execute a command every time a breakpoint is hit with 'e cmd.bp = !my-program'
[0x00000000]> pf [2]q[2]q[2]qq[2]qqqq[4]q blk_dva_0 blk_dva_1 blk_dva_2 blk_prop blk_pad[2] blk_phys_birth blk_birth blk_fill blk_cksum
blk_dva_0 : 0x00000000 = (qword)[ 0x0000000000000001, 0x0000000000000081 ]
blk_dva_1 : 0x00000010 = (qword)[ 0x0000000000000001, 0x0000000000000082 ]
blk_dva_2 : 0x00000020 = (qword)[ 0x0000000000000000, 0x0000000000000000 ]
blk_prop : 0x00000030 = (qword)0x830a070f0000001f
blk_pad[2] : 0x00000038 = (qword)[ 0x0000000000000000, 0x0000000000000000 ]
blk_phys_birth : 0x00000048 = (qword)0x0000000000000000
blk_birth : 0x00000050 = (qword)0x0000000000000038
blk_fill : 0x00000058 = (qword)0x0000000000000009
blk_cksum : 0x00000060 = (qword)[ 0x00000012cee6bcc2, 0x0000078b79b1c147, 0x000189aa5ace3a0a, 0x00365db1d10dc06e ]
L3
[0x00000000]> "? 0x400000/512 + 0x0000000000000081"
8321 0x2081 020201 8.1K 0000:0081 8321 "\x81 " 0b0010000010000001 8321.0 8321.000000f 8321.000000 0t102102012
# dd if=/tmp/test_disk bs=512 skip=8321 count=1 of=/tmp/os.dataset.dnode.l3.bin.lz4
# zdec os.dataset.dnode.l3.bin.lz4 os.dataset.dnode.l3.bin 16384
Input: os.dataset.dnode.l3.bin.lz4
Output: os.dataset.dnode.l3.bin
Out size: 16384
-----------------------------
Input size: 512
Real input size: 150
Decompress result: 0
# r2 os.dataset.dnode.l3.bin
-- Use the '[' and ']' keys in visual mode to adjust the screen width
[0x00000000]> pf [2]q[2]q[2]qq[2]qqqq[4]q blk_dva_0 blk_dva_1 blk_dva_2 blk_prop blk_pad[2] blk_phys_birth blk_birth blk_fill blk_cksum
blk_dva_0 : 0x00000000 = (qword)[ 0x0000000000000001, 0x00000000000000ea ]
blk_dva_1 : 0x00000010 = (qword)[ 0x0000000000000001, 0x0000000000000080 ]
blk_dva_2 : 0x00000020 = (qword)[ 0x0000000000000000, 0x0000000000000000 ]
blk_prop : 0x00000030 = (qword)0x820a070f0000001f
blk_pad[2] : 0x00000038 = (qword)[ 0x0000000000000000, 0x0000000000000000 ]
blk_phys_birth : 0x00000048 = (qword)0x0000000000000000
blk_birth : 0x00000050 = (qword)0x0000000000000038
blk_fill : 0x00000058 = (qword)0x0000000000000009
blk_cksum : 0x00000060 = (qword)[ 0x00000013d660f06c, 0x000007fd7a9a913f, 0x0001a28c7591888d, 0x003a04c5208f66a6 ]
L2
[0x00000000]> "? 0x400000/512 + 0x00000000000000ea"
8426 0x20ea 020352 8.2K 0000:00ea 8426 "\xea " 0b0010000011101010 8426.0 8426.000000f 8426.000000 0t102120002
# dd if=/tmp/test_disk bs=512 skip=8426 count=1 of=/tmp/os.dataset.dnode.l2.bin.lz4
# zdec os.dataset.dnode.l2.bin.lz4 os.dataset.dnode.l2.bin 16384
Input: os.dataset.dnode.l2.bin.lz4
Output: os.dataset.dnode.l2.bin
Out size: 16384
-----------------------------
Input size: 512
Real input size: 150
Decompress result: 0
# r2 os.dataset.dnode.l2.bin
[0x00000000]> pf [2]q[2]q[2]qq[2]qqqq[4]q blk_dva_0 blk_dva_1 blk_dva_2 blk_prop blk_pad[2] blk_phys_birth blk_birth blk_fill blk_cksum
blk_dva_0 : 0x00000000 = (qword)[ 0x0000000000000001, 0x000000000000007e ]
blk_dva_1 : 0x00000010 = (qword)[ 0x0000000000000001, 0x00000000000000d8 ]
blk_dva_2 : 0x00000020 = (qword)[ 0x0000000000000000, 0x0000000000000000 ]
blk_prop : 0x00000030 = (qword)0x810a070f0000001f
blk_pad[2] : 0x00000038 = (qword)[ 0x0000000000000000, 0x0000000000000000 ]
blk_phys_birth : 0x00000048 = (qword)0x0000000000000000
blk_birth : 0x00000050 = (qword)0x0000000000000038
blk_fill : 0x00000058 = (qword)0x0000000000000009
blk_cksum : 0x00000060 = (qword)[ 0x000000119de2c7aa, 0x00000700d12632b0, 0x000169e2d81be607, 0x00317850a78e8a46 ]
L1
[0x00000000]> "? 0x400000/512 + 0x000000000000007e"
8318 0x207e 020176 8.1K 0000:007e 8318 "~ " 0b0010000001111110 8318.0 8318.000000f 8318.000000 0t102102002
# dd if=/tmp/test_disk bs=512 skip=8318 count=1 of=/tmp/os.dataset.dnode.l1.bin.lz4
# zdec os.dataset.dnode.l1.bin.lz4 os.dataset.dnode.l1.bin 16384
Input: os.dataset.dnode.l1.bin.lz4
Output: os.dataset.dnode.l1.bin
Out size: 16384
-----------------------------
Input size: 512
Real input size: 150
Decompress result: 0
# r2 os.dataset.dnode.l1.bin
[0x00000000]> pf [2]q[2]q[2]qq[2]qqqq[4]q blk_dva_0 blk_dva_1 blk_dva_2 blk_prop blk_pad[2] blk_phys_birth blk_birth blk_fill blk_cksum
blk_dva_0 : 0x00000000 = (qword)[ 0x0000000000000002, 0x0000000000000105 ]
blk_dva_1 : 0x00000010 = (qword)[ 0x0000000000000002, 0x000000000000007c ]
blk_dva_2 : 0x00000020 = (qword)[ 0x0000000000000000, 0x0000000000000000 ]
blk_prop : 0x00000030 = (qword)0x800a070f0001001f
blk_pad[2] : 0x00000038 = (qword)[ 0x0000000000000000, 0x0000000000000000 ]
blk_phys_birth : 0x00000048 = (qword)0x0000000000000000
blk_birth : 0x00000050 = (qword)0x0000000000000038
blk_fill : 0x00000058 = (qword)0x0000000000000009
blk_cksum : 0x00000060 = (qword)[ 0x0000003e07b9461b, 0x00001c6526d2728c, 0x00097c6c15624af0, 0x0268557731d83b04 ]
L0
[0x00000000]> "? 0x400000/512 + 0x0000000000000105"
8453 0x2105 020405 8.3K 0000:0105 8453 "\x05!" 0b0010000100000101 8453.0 8453.000000f 8453.000000 0t102121002
# dd if=/tmp/test_disk bs=512 skip=8453 count=2 of=/tmp/os.dataset.dnode.l0.bin.lz4
# zdec os.dataset.dnode.l0.bin.lz4 os.dataset.dnode.l0.bin 16384
Input: os.dataset.dnode.l0.bin.lz4
Output: os.dataset.dnode.l0.bin
Out size: 16384
-----------------------------
Input size: 1024
Real input size: 1007
Decompress result: 0
ゼロレベルは直接objsetです。
オブジェクトのリストを作成する
9個のオブジェクト
# r2 os.dataset.dnode.l0.bin
[0x00000000]> s+0x200
[0x00000200]> pf bbbbbbbbww[4]bqq[4]q dn_type dn_indblkshift dn_nlevels dn_nblkptr dn_bonustype dn_checksum dn_compress dn_flags dn_datablkszsec dn_bonuslen dn_pad2[4] dn_maxblkid dn_used dn_pad3[4]
dn_type : 0x00000200 = 0x15
dn_indblkshift : 0x00000201 = 0x0e
dn_nlevels : 0x00000202 = 0x01
dn_nblkptr : 0x00000203 = 0x03
dn_bonustype : 0x00000204 = 0x00
dn_checksum : 0x00000205 = 0x00
dn_compress : 0x00000206 = 0x00
dn_flags : 0x00000207 = 0x03
dn_datablkszsec : 0x00000208 = 0x0001
dn_bonuslen : 0x0000020a = 0x0000
dn_pad2[4] : 0x0000020c = [ 0x00, 0x00, 0x00, 0x00 ]
dn_maxblkid : 0x00000210 = (qword)0x0000000000000000
dn_used : 0x00000218 = (qword)0x0000000000000400
dn_pad3[4] : 0x00000220 = (qword)[ 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000 ]
[0x00000200]> s+0x200
[0x00000400]> pf bbbbbbbbww[4]bqq[4]q dn_type dn_indblkshift dn_nlevels dn_nblkptr dn_bonustype dn_checksum dn_compress dn_flags dn_datablkszsec dn_bonuslen dn_pad2[4] dn_maxblkid dn_used dn_pad3[4]
dn_type : 0x00000400 = 0x2d
dn_indblkshift : 0x00000401 = 0x0e
dn_nlevels : 0x00000402 = 0x01
dn_nblkptr : 0x00000403 = 0x03
dn_bonustype : 0x00000404 = 0x00
dn_checksum : 0x00000405 = 0x00
dn_compress : 0x00000406 = 0x00
dn_flags : 0x00000407 = 0x03
dn_datablkszsec : 0x00000408 = 0x0001
dn_bonuslen : 0x0000040a = 0x0000
dn_pad2[4] : 0x0000040c = [ 0x00, 0x00, 0x00, 0x00 ]
dn_maxblkid : 0x00000410 = (qword)0x0000000000000000
dn_used : 0x00000418 = (qword)0x0000000000000000
dn_pad3[4] : 0x00000420 = (qword)[ 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000 ]
[0x00000400]> s+0x200
[0x00000600]> pf bbbbbbbbww[4]bqq[4]q dn_type dn_indblkshift dn_nlevels dn_nblkptr dn_bonustype dn_checksum dn_compress dn_flags dn_datablkszsec dn_bonuslen dn_pad2[4] dn_maxblkid dn_used dn_pad3[4]
dn_type : 0x00000600 = 0x16
dn_indblkshift : 0x00000601 = 0x0e
dn_nlevels : 0x00000602 = 0x01
dn_nblkptr : 0x00000603 = 0x03
dn_bonustype : 0x00000604 = 0x00
dn_checksum : 0x00000605 = 0x00
dn_compress : 0x00000606 = 0x00
dn_flags : 0x00000607 = 0x03
dn_datablkszsec : 0x00000608 = 0x0001
dn_bonuslen : 0x0000060a = 0x0000
dn_pad2[4] : 0x0000060c = [ 0x00, 0x00, 0x00, 0x00 ]
dn_maxblkid : 0x00000610 = (qword)0x0000000000000000
dn_used : 0x00000618 = (qword)0x0000000000000000
dn_pad3[4] : 0x00000620 = (qword)[ 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000 ]
[0x00000600]> s+0x200
[0x00000800]> pf bbbbbbbbww[4]bqq[4]q dn_type dn_indblkshift dn_nlevels dn_nblkptr dn_bonustype dn_checksum dn_compress dn_flags dn_datablkszsec dn_bonuslen dn_pad2[4] dn_maxblkid dn_used dn_pad3[4]
dn_type : 0x00000800 = 0x14
dn_indblkshift : 0x00000801 = 0x0e
dn_nlevels : 0x00000802 = 0x01
dn_nblkptr : 0x00000803 = 0x01
dn_bonustype : 0x00000804 = 0x2c
dn_checksum : 0x00000805 = 0x00
dn_compress : 0x00000806 = 0x00
dn_flags : 0x00000807 = 0x03
dn_datablkszsec : 0x00000808 = 0x0001
dn_bonuslen : 0x0000080a = 0x00a8
dn_pad2[4] : 0x0000080c = [ 0x00, 0x00, 0x00, 0x00 ]
dn_maxblkid : 0x00000810 = (qword)0x0000000000000000
dn_used : 0x00000818 = (qword)0x0000000000000000
dn_pad3[4] : 0x00000820 = (qword)[ 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000 ]
[0x00000800]> s+0x200
[0x00000a00]> pf bbbbbbbbww[4]bqq[4]q dn_type dn_indblkshift dn_nlevels dn_nblkptr dn_bonustype dn_checksum dn_compress dn_flags dn_datablkszsec dn_bonuslen dn_pad2[4] dn_maxblkid dn_used dn_pad3[4]
dn_type : 0x00000a00 = 0x2e
dn_indblkshift : 0x00000a01 = 0x0e
dn_nlevels : 0x00000a02 = 0x01
dn_nblkptr : 0x00000a03 = 0x03
dn_bonustype : 0x00000a04 = 0x00
dn_checksum : 0x00000a05 = 0x00
dn_compress : 0x00000a06 = 0x00
dn_flags : 0x00000a07 = 0x03
dn_datablkszsec : 0x00000a08 = 0x0003
dn_bonuslen : 0x00000a0a = 0x0000
dn_pad2[4] : 0x00000a0c = [ 0x00, 0x00, 0x00, 0x00 ]
dn_maxblkid : 0x00000a10 = (qword)0x0000000000000000
dn_used : 0x00000a18 = (qword)0x0000000000000400
dn_pad3[4] : 0x00000a20 = (qword)[ 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000 ]
[0x00000a00]> s+0x200
[0x00000c00]> pf bbbbbbbbww[4]bqq[4]q dn_type dn_indblkshift dn_nlevels dn_nblkptr dn_bonustype dn_checksum dn_compress dn_flags dn_datablkszsec dn_bonuslen dn_pad2[4] dn_maxblkid dn_used dn_pad3[4]
dn_type : 0x00000c00 = 0x2f
dn_indblkshift : 0x00000c01 = 0x0e
dn_nlevels : 0x00000c02 = 0x01
dn_nblkptr : 0x00000c03 = 0x03
dn_bonustype : 0x00000c04 = 0x00
dn_checksum : 0x00000c05 = 0x00
dn_compress : 0x00000c06 = 0x00
dn_flags : 0x00000c07 = 0x03
dn_datablkszsec : 0x00000c08 = 0x0020
dn_bonuslen : 0x00000c0a = 0x0000
dn_pad2[4] : 0x00000c0c = [ 0x00, 0x00, 0x00, 0x00 ]
dn_maxblkid : 0x00000c10 = (qword)0x0000000000000001
dn_used : 0x00000c18 = (qword)0x0000000000002000
dn_pad3[4] : 0x00000c20 = (qword)[ 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000 ]
[0x00000c00]> s+0x200
[0x00000e00]> pf bbbbbbbbww[4]bqq[4]q dn_type dn_indblkshift dn_nlevels dn_nblkptr dn_bonustype dn_checksum dn_compress dn_flags dn_datablkszsec dn_bonuslen dn_pad2[4] dn_maxblkid dn_used dn_pad3[4]
dn_type : 0x00000e00 = 0x13
dn_indblkshift : 0x00000e01 = 0x0e
dn_nlevels : 0x00000e02 = 0x01
dn_nblkptr : 0x00000e03 = 0x01
dn_bonustype : 0x00000e04 = 0x2c
dn_checksum : 0x00000e05 = 0x00
dn_compress : 0x00000e06 = 0x00
dn_flags : 0x00000e07 = 0x02
dn_datablkszsec : 0x00000e08 = 0x0001
dn_bonuslen : 0x00000e0a = 0x00a8
dn_pad2[4] : 0x00000e0c = [ 0x00, 0x00, 0x00, 0x00 ]
dn_maxblkid : 0x00000e10 = (qword)0x0000000000000000
dn_used : 0x00000e18 = (qword)0x0000000000000000
dn_pad3[4] : 0x00000e20 = (qword)[ 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000 ]
[0x00000e00]> s+0x200
[0x00001000]> pf bbbbbbbbww[4]bqq[4]q dn_type dn_indblkshift dn_nlevels dn_nblkptr dn_bonustype dn_checksum dn_compress dn_flags dn_datablkszsec dn_bonuslen dn_pad2[4] dn_maxblkid dn_used dn_pad3[4]
dn_type : 0x00001000 = 0x13
dn_indblkshift : 0x00001001 = 0x0e
dn_nlevels : 0x00001002 = 0x01
dn_nblkptr : 0x00001003 = 0x01
dn_bonustype : 0x00001004 = 0x2c
dn_checksum : 0x00001005 = 0x00
dn_compress : 0x00001006 = 0x00
dn_flags : 0x00001007 = 0x03
dn_datablkszsec : 0x00001008 = 0x0001
dn_bonuslen : 0x0000100a = 0x00a8
dn_pad2[4] : 0x0000100c = [ 0x00, 0x00, 0x00, 0x00 ]
dn_maxblkid : 0x00001010 = (qword)0x0000000000000000
dn_used : 0x00001018 = (qword)0x0000000000000200
dn_pad3[4] : 0x00001020 = (qword)[ 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000 ]
[0x00001000]> s+0x200
[0x00001200]> pf bbbbbbbbww[4]bqq[4]q dn_type dn_indblkshift dn_nlevels dn_nblkptr dn_bonustype dn_checksum dn_compress dn_flags dn_datablkszsec dn_bonuslen dn_pad2[4] dn_maxblkid dn_used dn_pad3[4]
dn_type : 0x00001200 = 0x13
dn_indblkshift : 0x00001201 = 0x0e
dn_nlevels : 0x00001202 = 0x02
dn_nblkptr : 0x00001203 = 0x01
dn_bonustype : 0x00001204 = 0x2c
dn_checksum : 0x00001205 = 0x00
dn_compress : 0x00001206 = 0x00
dn_flags : 0x00001207 = 0x03
dn_datablkszsec : 0x00001208 = 0x0001
dn_bonuslen : 0x0000120a = 0x00a8
dn_pad2[4] : 0x0000120c = [ 0x00, 0x00, 0x00, 0x00 ]
dn_maxblkid : 0x00001210 = (qword)0x0000000000000001
dn_used : 0x00001218 = (qword)0x0000000000000800
dn_pad3[4] : 0x00001220 = (qword)[ 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000 ]
インデックス | dn_type | dn_bonustype | dn_bonuslen | ||
4 | 0x14 | DMU_OT_DIRECTORY_CONTENTS | 0x2c | DMU_OT_SA | 0x00a8 |
7 | 0x13 | DMU_OT_PLAIN_FILE_CONTENTS | 0x2c | DMU_OT_SA | 0x00a8 |
8 | 0x13 | DMU_OT_PLAIN_FILE_CONTENTS | 0x2c | DMU_OT_SA | 0x00a8 |
9 | 0x13 | DMU_OT_PLAIN_FILE_CONTENTS | 0x2c | DMU_OT_SA | 0x00a8 |
オブジェクト7、8、9は、作成したファイル0B、512B、513Bです。 番号とファイルの対応は、オブジェクト4(DMU_OT_DIRECTORY_CONTENTS)から取得できます。
オブジェクトのカウント4
# r2 os.dataset.dnode.l0.bin
[0x00001400]> 0x00000800
[0x00000800]> s+0x40
[0x00000840]> pf [2]q[2]q[2]qq[2]qqqq[4]q blk_dva_0 blk_dva_1 blk_dva_2 blk_prop blk_pad[2] blk_phys_birth blk_birth blk_fill blk_cksum
blk_dva_0 : 0x00000840 = (qword)[ 0x0100032143000000, 0x0cfd073129805300 ]
blk_dva_1 : 0x00000850 = (qword)[ 0x2e07121a00020f00, 0x4230220007801200 ]
blk_dva_2 : 0x00000860 = (qword)[ 0x08121700020f0008, 0x31353f004003002b ]
blk_prop : 0x00000870 = (qword)0x8014008f8c0001ff
blk_pad[2] : 0x00000878 = (qword)[ 0x0040091b1c004232, 0x00020f1c0040331f ]
blk_phys_birth : 0x00000888 = (qword)0x00000000000050e8
blk_birth : 0x00000890 = (qword)0x0000000000000022
blk_fill : 0x00000898 = (qword)0x0000000000000000
blk_cksum : 0x000008a0 = (qword)[ 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000 ]
これはEmbedded blkptr(ビットE)であり、構造は通常のblkptrとは異なります。

データは構造に直接保存されます。
[0x00000840]> pf [48]bq[24]bq[40]b data_1 blk_prob data_2 txg data_3
data_1 : 0x00000840 = [ 0x00, 0x00, 0x00, 0x43, 0x21, 0x03, 0x00, 0x01, 0x00, 0x53, 0x80, 0x29, 0x31, 0x07, 0xfd, 0x0c, 0x00, 0x0f, 0x02, 0x00, 0x1a, 0x12, 0x07, 0x2e, 0x00, 0x12, 0x80, 0x07, 0x00, 0x22, 0x30, 0x42, 0x08, 0x00, 0x0f, 0x02, 0x00, 0x17, 0x12, 0x08, 0x2b, 0x00, 0x03, 0x40, 0x00, 0x3f, 0x35, 0x31 ]
blk_prob : 0x00000870 = (qword)0x8014008f8c0001ff
data_2 : 0x00000878 = [ 0x32, 0x42, 0x00, 0x1c, 0x1b, 0x09, 0x40, 0x00, 0x1f, 0x33, 0x40, 0x00, 0x1c, 0x0f, 0x02, 0x00, 0xe8, 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ]
txg : 0x00000890 = (qword)0x0000000000000022
data_3 : 0x00000898 = [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ]
このデータをファイルに読み込む
48バイトを順番にコピーし、残りの23バイトをblk_prob(8バイト)スキップします(フルサイズはPSIZEフィールドから取得されます)。
# dd if=os.dataset.dnode.l0.bin of=/tmp/emb.bin.lz4 bs=1 count=48 skip=2112
# dd if=os.dataset.dnode.l0.bin of=/tmp/emb.bin.lz4 bs=1 seek=48 count=23 skip=2168
# zdec emb.bin.lz4 emb.bin 512
Input: emb.bin.lz4
Output: emb.bin
Out size: 512
-----------------------------
Input size: 71
Real input size: 67
Decompress result: 0
# r2 emb.bin
[0x00000000]> pf qqq[5]qqxwz mz_block_type mz_salt mz_normflags mz_pad[5] mz_chunk[1]_mze_value mz_chunk[1]_mze_cd mz_chunk[1]_mze_pad mz_chunk[1]_mze_name
mz_block_type : 0x00000000 = (qword)0x8000000000000003
mz_salt : 0x00000008 = (qword)0x00000003fd073129
mz_normflags : 0x00000010 = (qword)0x0000000000000000
mz_pad[5] : 0x00000018 = (qword)[ 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000 ]
mz_chunk[1]_mze_value : 0x00000040 = (qword)0x8000000000000007
mz_chunk[1]_mze_cd : 0x00000048 = 0x00000000
mz_chunk[1]_mze_pad : 0x0000004c = 0x0000
mz_chunk[1]_mze_name : 0x0000004e = 0B
[0x00000000]> s+0x80
[0x00000080]> pf qxwz mze_value mze_cd mze_pad mze_name
mze_value : 0x00000080 = (qword)0x8000000000000008
mze_cd : 0x00000088 = 0x00000000
mze_pad : 0x0000008c = 0x0000
mze_name : 0x0000008e = 512B
[0x00000080]> s+0x40
[0x000000c0]> pf qxwz mze_value mze_cd mze_pad mze_name
mze_value : 0x000000c0 = (qword)0x8000000000000009
mze_cd : 0x000000c8 = 0x00000000
mze_pad : 0x000000cc = 0x0000
mze_name : 0x000000ce = 513B
mze_value : 0x8000000000000007
ZFS_DIRENT_TYPE : 8 // "? (0x8000000000000007>60)&((1<4)-1)" // /* 8 */ "Regular File",
ZFS_DIRENT_OBJ : 7 // "? (0x8000000000000007>0)&((1<48)-1)" // Object id
0Bファイルは番号7です
512Bファイル番号8
513Bファイル番号9
オブジェクトのカウント7
# r2 os.dataset.dnode.l0.bin
[0x00000000]> 0x00000e00
[0x00000e00]> s+0x40
[0x00000e40]> pf [2]q[2]q[2]qq[2]qqqq[4]q blk_dva_0 blk_dva_1 blk_dva_2 blk_prop blk_pad[2] blk_phys_birth blk_birth blk_fill blk_cksum
blk_dva_0 : 0x00000e40 = (qword)[ 0x0000000000000000, 0x0000000000000000 ]
blk_dva_1 : 0x00000e50 = (qword)[ 0x0000000000000000, 0x0000000000000000 ]
blk_dva_2 : 0x00000e60 = (qword)[ 0x0000000000000000, 0x0000000000000000 ]
blk_prop : 0x00000e70 = (qword)0x0000000000000000
blk_pad[2] : 0x00000e78 = (qword)[ 0x0000000000000000, 0x0000000000000000 ]
blk_phys_birth : 0x00000e88 = (qword)0x0000000000000000
blk_birth : 0x00000e90 = (qword)0x0000000000000000
blk_fill : 0x00000e98 = (qword)0x0000000000000000
blk_cksum : 0x00000ea0 = (qword)[ 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000 ]
ファイルにデータが含まれていません-blkptrは空です。
オブジェクトのカウント8
[0x00000e40]> 0x00001000
[0x00001000]> s+0x40
[0x00001040]> pf [2]q[2]q[2]qq[2]qqqq[4]q blk_dva_0 blk_dva_1 blk_dva_2 blk_prop blk_pad[2] blk_phys_birth blk_birth blk_fill blk_cksum
blk_dva_0 : 0x00001040 = (qword)[ 0x0000000000000001, 0x00000000000000e9 ]
blk_dva_1 : 0x00001050 = (qword)[ 0x0000000000000000, 0x0000000000000000 ]
blk_dva_2 : 0x00001060 = (qword)[ 0x0000000000000000, 0x0000000000000000 ]
blk_prop : 0x00001070 = (qword)0x8013070200000000
blk_pad[2] : 0x00001078 = (qword)[ 0x0000000000000000, 0x0000000000000000 ]
blk_phys_birth : 0x00001088 = (qword)0x0000000000000000
blk_birth : 0x00001090 = (qword)0x0000000000000020
blk_fill : 0x00001098 = (qword)0x0000000000000001
blk_cksum : 0x000010a0 = (qword)[ 0x0000003c34e2ea5c, 0x00000f3db2d3ec9f, 0x00029bdcc6458734, 0x005654ddd2b56e82 ]

ファイルはディスク上の1つのセクターを占有します。 512バイト
オブジェクトのカウント9
[0x00001040]> 0x1200
[0x00001200]> s+0x40
[0x00001240]> pf [2]q[2]q[2]qq[2]qqqq[4]q blk_dva_0 blk_dva_1 blk_dva_2 blk_prop blk_pad[2] blk_phys_birth blk_birth blk_fill blk_cksum
blk_dva_0 : 0x00001240 = (qword)[ 0x0000000000000001, 0x000000000000009d ]
blk_dva_1 : 0x00001250 = (qword)[ 0x0000000000000001, 0x0000000000000059 ]
blk_dva_2 : 0x00001260 = (qword)[ 0x0000000000000000, 0x0000000000000000 ]
blk_prop : 0x00001270 = (qword)0x8113070f0000001f
blk_pad[2] : 0x00001278 = (qword)[ 0x0000000000000000, 0x0000000000000000 ]
blk_phys_birth : 0x00001288 = (qword)0x0000000000000000
blk_birth : 0x00001290 = (qword)0x0000000000000022
blk_fill : 0x00001298 = (qword)0x0000000000000002
blk_cksum : 0x000012a0 = (qword)[ 0x0000001427d4c96a, 0x000007e5038b685d, 0x000194254db44203, 0x0037093ef743abcc ]

513バイトのファイルは、512バイトに等しいrecordsizeに完全には収まらず、間接ブロックを使用して保存します。
間接ブロックは重複して保存されます(blk_dva_0およびblk_dva_1)。
したがって、ディスク上のファイルサイズ:
0B:dnode(512B)= 512バイト
512B:dnode(512B)+ファイルデータ(512B)= 1024バイト
513B:dnode(512B)+ 2 *間接ブロック(512B)+ 2 *ファイルデータ(512B)= 2560バイト
lz4アルゴリズムで圧縮されたブロックを解凍するプログラム
lz4.cファイルからのLZ4_uncompress_unknownOutputSize関数のコピーを表します
#include <iostream> #include <fstream> #include <cstdint> #include <cstring> using namespace std; static int LZ4_uncompress_unknownOutputSize(const char *source, char *dest, int isize, int maxOutputSize); #define BE_IN8(xa) \ *((uint8_t *)(xa)) #define BE_IN16(xa) \ (((uint16_t)BE_IN8(xa) << 8) | BE_IN8((uint8_t *)(xa)+1)) #define BE_IN32(xa) \ (((uint32_t)BE_IN16(xa) << 16) | BE_IN16((uint8_t *)(xa)+2)) #define COMPRESSIONLEVEL 12 #define NOTCOMPRESSIBLE_CONFIRMATION 6 /* * * CPU Feature Detection */ /* 32 or 64 bits ? */ #if defined(_LP64) #define LZ4_ARCH64 1 #else #define LZ4_ARCH64 0 #endif /* * Little Endian or Big Endian? * Note: overwrite the below #define if you know your architecture endianess. */ #if defined(_BIG_ENDIAN) #define LZ4_BIG_ENDIAN 1 #else /* * Little Endian assumed. PDP Endian and other very rare endian format * are unsupported. */ #undef LZ4_BIG_ENDIAN #endif /* * Unaligned memory access is automatically enabled for "common" CPU, * such as x86. For others CPU, the compiler will be more cautious, and * insert extra code to ensure aligned access is respected. If you know * your target CPU supports unaligned memory access, you may want to * force this option manually to improve performance */ #if defined(__ARM_FEATURE_UNALIGNED) #define LZ4_FORCE_UNALIGNED_ACCESS 1 #endif /* * Illumos : we can't use GCC's __builtin_ctz family of builtins in the * kernel * Linux : we can use GCC's __builtin_ctz family of builtins in the * kernel */ #undef LZ4_FORCE_SW_BITCOUNT #if defined(__sparc) #define LZ4_FORCE_SW_BITCOUNT #endif /* * Compiler Options */ /* Disable restrict */ #define restrict /* * Linux : GCC_VERSION is defined as of 3.9-rc1, so undefine it. * torvalds/linux@3f3f8d2f48acfd8ed3b8e6b7377935da57b27b16 */ #ifdef GCC_VERSION #undef GCC_VERSION #endif #define GCC_VERSION (__GNUC__ * 100 + __GNUC_MINOR__) #if (GCC_VERSION >= 302) || (__INTEL_COMPILER >= 800) || defined(__clang__) #define expect(expr, value) (__builtin_expect((expr), (value))) #else #define expect(expr, value) (expr) #endif #ifndef likely #define likely(expr) expect((expr) != 0, 1) #endif #ifndef unlikely #define unlikely(expr) expect((expr) != 0, 0) #endif #define lz4_bswap16(x) ((unsigned short int) ((((x) >> 8) & 0xffu) | \ (((x) & 0xffu) << 8))) /* Basic types */ #define BYTE uint8_t #define U16 uint16_t #define U32 uint32_t #define S32 int32_t #define U64 uint64_t #ifndef LZ4_FORCE_UNALIGNED_ACCESS #pragma pack(1) #endif typedef struct _U16_S { U16 v; } U16_S; typedef struct _U32_S { U32 v; } U32_S; typedef struct _U64_S { U64 v; } U64_S; #ifndef LZ4_FORCE_UNALIGNED_ACCESS #pragma pack() #endif #define A64(x) (((U64_S *)(x))->v) #define A32(x) (((U32_S *)(x))->v) #define A16(x) (((U16_S *)(x))->v) /* * Constants */ #define MINMATCH 4 #define HASH_LOG COMPRESSIONLEVEL #define HASHTABLESIZE (1 << HASH_LOG) #define HASH_MASK (HASHTABLESIZE - 1) #define SKIPSTRENGTH (NOTCOMPRESSIBLE_CONFIRMATION > 2 ? \ NOTCOMPRESSIBLE_CONFIRMATION : 2) #define COPYLENGTH 8 #define LASTLITERALS 5 #define MFLIMIT (COPYLENGTH + MINMATCH) #define MINLENGTH (MFLIMIT + 1) #define MAXD_LOG 16 #define MAX_DISTANCE ((1 << MAXD_LOG) - 1) #define ML_BITS 4 #define ML_MASK ((1U<<ML_BITS)-1) #define RUN_BITS (8-ML_BITS) #define RUN_MASK ((1U<<RUN_BITS)-1) /* * Architecture-specific macros */ #if LZ4_ARCH64 #define STEPSIZE 8 #define UARCH U64 #define AARCH A64 #define LZ4_COPYSTEP(s, d) A64(d) = A64(s); d += 8; s += 8; #define LZ4_COPYPACKET(s, d) LZ4_COPYSTEP(s, d) #define LZ4_SECURECOPY(s, d, e) if (d < e) LZ4_WILDCOPY(s, d, e) #define HTYPE U32 #define INITBASE(base) const BYTE* const base = ip #else /* !LZ4_ARCH64 */ #define STEPSIZE 4 #define UARCH U32 #define AARCH A32 #define LZ4_COPYSTEP(s, d) A32(d) = A32(s); d += 4; s += 4; #define LZ4_COPYPACKET(s, d) LZ4_COPYSTEP(s, d); LZ4_COPYSTEP(s, d); #define LZ4_SECURECOPY LZ4_WILDCOPY #define HTYPE const BYTE * #define INITBASE(base) const int base = 0 #endif /* !LZ4_ARCH64 */ #if (defined(LZ4_BIG_ENDIAN) && !defined(BIG_ENDIAN_NATIVE_BUT_INCOMPATIBLE)) #define LZ4_READ_LITTLEENDIAN_16(d, s, p) \ { U16 v = A16(p); v = lz4_bswap16(v); d = (s) - v; } #define LZ4_WRITE_LITTLEENDIAN_16(p, i) \ { U16 v = (U16)(i); v = lz4_bswap16(v); A16(p) = v; p += 2; } #else #define LZ4_READ_LITTLEENDIAN_16(d, s, p) { d = (s) - A16(p); } #define LZ4_WRITE_LITTLEENDIAN_16(p, v) { A16(p) = v; p += 2; } #endif /* Local structures */ struct refTables { HTYPE hashTable[HASHTABLESIZE]; }; /* Macros */ #define LZ4_HASH_FUNCTION(i) (((i) * 2654435761U) >> ((MINMATCH * 8) - \ HASH_LOG)) #define LZ4_HASH_VALUE(p) LZ4_HASH_FUNCTION(A32(p)) #define LZ4_WILDCOPY(s, d, e) do { LZ4_COPYPACKET(s, d) } while (d < e); #define LZ4_BLINDCOPY(s, d, l) { BYTE* e = (d) + l; LZ4_WILDCOPY(s, d, e); \ d = e; } static int LZ4_uncompress_unknownOutputSize(const char *source, char *dest, int isize, int maxOutputSize) { /* Local Variables */ const BYTE *restrict ip = (const BYTE *) source; const BYTE *const iend = ip + isize; const BYTE *ref; BYTE *op = (BYTE *) dest; BYTE *const oend = op + maxOutputSize; BYTE *cpy; size_t dec32table[] = {0, 3, 2, 3, 0, 0, 0, 0}; #if LZ4_ARCH64 size_t dec64table[] = {0, 0, 0, (size_t)-1, 0, 1, 2, 3}; #endif /* Main Loop */ while (ip < iend) { unsigned token; size_t length; /* get runlength */ token = *ip++; if ((length = (token >> ML_BITS)) == RUN_MASK) { int s = 255; while ((ip < iend) && (s == 255)) { s = *ip++; length += s; } } /* copy literals */ cpy = op + length; /* CORNER-CASE: cpy might overflow. */ if (cpy < op) goto _output_error; /* cpy was overflowed, bail! */ if ((cpy > oend - COPYLENGTH) || (ip + length > iend - COPYLENGTH)) { if (cpy > oend) /* Error: writes beyond output buffer */ goto _output_error; if (ip + length != iend) /* * Error: LZ4 format requires to consume all * input at this stage */ goto _output_error; (void) memcpy(op, ip, length); op += length; /* Necessarily EOF, due to parsing restrictions */ break; } LZ4_WILDCOPY(ip, op, cpy); ip -= (op - cpy); op = cpy; /* get offset */ LZ4_READ_LITTLEENDIAN_16(ref, cpy, ip); ip += 2; if (ref < (BYTE * const) dest) /* * Error: offset creates reference outside of * destination buffer */ goto _output_error; /* get matchlength */ if ((length = (token & ML_MASK)) == ML_MASK) { while (ip < iend) { int s = *ip++; length += s; if (s == 255) continue; break; } } /* copy repeated sequence */ if (unlikely(op - ref < STEPSIZE)) { #if LZ4_ARCH64 size_t dec64 = dec64table[op-ref]; #else const int dec64 = 0; #endif op[0] = ref[0]; op[1] = ref[1]; op[2] = ref[2]; op[3] = ref[3]; op += 4; ref += 4; ref -= dec32table[op-ref]; A32(op) = A32(ref); op += STEPSIZE - 4; ref -= dec64; } else { LZ4_COPYSTEP(ref, op); } cpy = op + length - (STEPSIZE - 4); if (cpy > oend - COPYLENGTH) { if (cpy > oend) /* * Error: request to write outside of * destination buffer */ goto _output_error; LZ4_SECURECOPY(ref, op, (oend - COPYLENGTH)); while (op < cpy) *op++ = *ref++; op = cpy; if (op == oend) /* * Check EOF (should never happen, since * last 5 bytes are supposed to be literals) */ goto _output_error; continue; } LZ4_SECURECOPY(ref, op, cpy); op = cpy; /* correction */ } /* end of decoding */ return (int)(((char *)op) - dest); /* write overflow error detected */ _output_error: return (int)(-(((char *)ip) - source)); } /*ARGSUSED*/ int lz4_decompress_zfs(void *s_start, void *d_start, size_t s_len, size_t d_len, int n) { const char *src = (const char*) s_start; uint32_t bufsiz = BE_IN32(src); /* invalid compressed buffer size encoded at start */ if (bufsiz + sizeof (bufsiz) > s_len) return (1); std::cout << "Real input size: " << bufsiz << std::endl; /* * Returns 0 on success (decompression function returned non-negative) * and non-zero on failure (decompression function returned negative. */ return (LZ4_uncompress_unknownOutputSize(&src[sizeof (bufsiz)], (char*)d_start, bufsiz, d_len) < 0); } int main( int argc, char **argv ) { if (argc < 4) { std::cout << argv[0] << " <in> <out> <out_size>" << std::endl; return 1; } char* szInput = argv[1]; char* szOutput = argv[2]; int nOutSize = atoi(argv[3]); std::cout << "Input: \t\t" << szInput << std::endl; std::cout << "Output: \t" << szOutput << std::endl; std::cout << "Out size: \t" << nOutSize << std::endl; std::cout << "-----------------------------" << std::endl; // READ INPUT fstream fs(szInput, fstream::in); if (!fs.is_open()) { std::cout << "Open error"; return 1; } fs.seekg(0, ios::end); int fileSize = fs.tellg(); std::cout << "Input size: \t" << fileSize << std::endl; char* src = new char[fileSize]; fs.seekg(0, ios::beg); fs.read(src, fileSize); if (!fs) { std::cout << "error: only " << fs.gcount() << " could be read"; fs.close(); return 1; } fs.close(); // END READ INPUT // DECOMPRESS char* dst = new char[nOutSize]; std::memset(dst, 0, nOutSize); int nRes = lz4_decompress_zfs(src, dst, fileSize, nOutSize, 0); std::cout << "Decompress result: " << nRes << std::endl; if (nRes) { std::cout << "Decompress error" << std::endl; // return 1; } // END DECOMPRESS // OUTPUT fstream out(szOutput, fstream::out); if (!out.is_open()) { std::cout << "Open error"; return 1; } out.write(dst, nOutSize); if (!out) { std::cout << "error: only " << out.gcount() << " could be write"; out.close(); return 1; } out.close(); // END OUTPUT delete[] src; delete[] dst; return 0; }