ZFSがデータを保存する方法

Zfsは、長期的なデータストレージ用として非常に人気のあるファイルシステムです。 さらに、データとそのチェックサムとともに保存することにより、記録されたデータの整合性を確保します。 チェックサムメカニズムにより、破損したデータを特定し、冗長性が存在する場合に復元できます。



この記事では、実用的な例で、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; }
      
      








All Articles