From 8a9764c34ea643308eed074c3fef1579dabe8461 Mon Sep 17 00:00:00 2001 From: Toomas Soome Date: Mon, 29 Jun 2015 08:54:07 +0300 Subject: [PATCH] 6041 SPARC boot should support LZ4 Reviewed by: Igor Kozhukhov Approved by: Richard Lowe --- usr/src/psm/stand/bootblks/common/mkbb.sh | 8 +- usr/src/psm/stand/bootblks/zfs/common/boot-zfs.fth | 2 +- usr/src/psm/stand/bootblks/zfs/common/zfs.fth | 274 ++++++++++++++++++++- 3 files changed, 273 insertions(+), 11 deletions(-) diff --git a/usr/src/psm/stand/bootblks/common/mkbb.sh b/usr/src/psm/stand/bootblks/common/mkbb.sh index d5d395d1fd..115126ed1e 100755 --- a/usr/src/psm/stand/bootblks/common/mkbb.sh +++ b/usr/src/psm/stand/bootblks/common/mkbb.sh @@ -23,10 +23,6 @@ # Copyright 2007 Sun Microsystems, Inc. All rights reserved. # Use is subject to license terms. # -#ident "%Z%%M% %I% %E% SMI" -# - -#!/bin/sh # defaults bblen=7680 @@ -75,8 +71,8 @@ dd if=$2 of=$3 conv=notrunc bs=1 oseek=$rdoff # if [ $totlen -gt $bblen ]; then extsize=$(ls -l $extra | awk -e '{ print $5 }') - if [ $extsize -gt 8192 ]; then - printf "$1 must be smaller than 8k\n" + if [ $extsize -gt 16384 ]; then + printf "$1 must be smaller than 16k\n" exit -1 fi dd if=$extra of=$3 conv=notrunc bs=1 oseek=$bblen diff --git a/usr/src/psm/stand/bootblks/zfs/common/boot-zfs.fth b/usr/src/psm/stand/bootblks/zfs/common/boot-zfs.fth index 2b3f5dd2d6..41a614432b 100644 --- a/usr/src/psm/stand/bootblks/zfs/common/boot-zfs.fth +++ b/usr/src/psm/stand/bootblks/zfs/common/boot-zfs.fth @@ -29,7 +29,7 @@ copyright: Copyright 2009 Sun Microsystems, Inc. All Rights Reserved \ big bootblk create bigbootblk -d# 8192 constant /fs-fcode +d# 16384 constant /fs-fcode \ Set the offset to the correct zfs boot block area. This area is at offset 512K d# 512 d# 1024 * constant fs-offset diff --git a/usr/src/psm/stand/bootblks/zfs/common/zfs.fth b/usr/src/psm/stand/bootblks/zfs/common/zfs.fth index 2c6c80f6ca..569a845f08 100644 --- a/usr/src/psm/stand/bootblks/zfs/common/zfs.fth +++ b/usr/src/psm/stand/bootblks/zfs/common/zfs.fth @@ -22,6 +22,7 @@ \ Copyright 2010 Sun Microsystems, Inc. All rights reserved. \ Use is subject to license terms. \ +\ Copyright 2015 Toomas Soome purpose: ZFS file system support package @@ -159,6 +160,259 @@ new-device 2drop 2drop r> drop ( ) ; + \ decode lz4 buffer header, returns src addr and len + : lz4_sbuf ( addr -- s_addr s_len ) + dup C@ 8 lshift swap 1+ ( byte0 addr++ ) + dup C@ ( byte0 addr byte1 ) + rot ( addr byte1 byte0 ) + or d# 16 lshift swap 1+ ( d addr++ ) + + dup C@ 8 lshift ( d addr byte2 ) + swap 1+ ( d byte2 addr++ ) + dup C@ swap 1+ ( d byte2 byte3 addr++ ) + -rot ( d s_addr byte2 byte3 ) + or ( d s_addr d' ) + rot ( s_addr d' d ) + or ( s_addr s_len ) + ; + + 4 constant STEPSIZE + 8 constant COPYLENGTH + 5 constant LASTLITERALS + 4 constant ML_BITS + d# 15 constant ML_MASK \ (1<r swap \ save original dest to return stack. + rot ( dest len src ) + lz4_sbuf ( dest len s_buf s_len ) + over + ( dest len s_buf s_end ) + 2swap ( s_buf s_end dest len ) + over + ( s_buf s_end dest dest_end ) + 2swap ( dest dest_end s_buf s_end ) + + \ main loop + begin 2dup < while + swap dup C@ ( dest dest_end s_end s_buf token ) + swap CHAR+ swap ( dest dest_end s_end s_buf++ token ) + dup ML_BITS rshift ( dest dest_end s_end s_buf token length ) + >r rot rot r> ( dest dest_end token s_end s_buf length ) + dup RUN_MASK = if + d# 255 begin ( dest dest_end token s_end s_buf length s ) + swap ( dest dest_end token s_end s_buf s length ) + >r >r ( ... R: length s ) + 2dup > ( dest dest_end token s_end s_buf flag ) + r@ d# 255 = and ( dest dest_end token s_end s_buf flag R: length s ) + r> swap r> swap ( dest dest_end token s_end s_buf s length flag ) + >r swap r> ( dest dest_end token s_end s_buf length s flag ) + while + drop >r ( dest dest_end token s_end s_buf R: length ) + dup c@ swap CHAR+ ( dest dest_end token s_end s s_buf++ ) + swap ( dest dest_end token s_end s_buf s ) + dup ( dest dest_end token s_end s_buf s s ) + r> + swap ( dest dest_end token s_end s_buf length s ) + repeat + drop ( dest dest_end token s_end s_buf length ) + then + + -rot ( dest dest_end token length s_end s_buf ) + swap >r >r ( dest dest_end token length R: s_end s_buf ) + swap >r ( dest dest_end length R: s_end s_buf token ) + rot ( dest_end length dest ) + 2dup + ( dest_end length dest cpy ) + + 2dup > if ( dest > cpy ) + " lz4 overflow" die + then + + 3 pick COPYLENGTH - over < ( dest_end length dest cpy flag ) + 3 pick ( dest_end length dest cpy flag length ) + r> ( dest_end length dest cpy flag length token ) + r> ( dest_end length dest cpy flag length token s_buf R: s_end ) + rot ( dest_end length dest cpy flag token s_buf length ) + over + ( dest_end length dest cpy flag token s_buf length+s_buf ) + r@ COPYLENGTH - > ( dest_end length dest cpy flag token s_buf flag ) + swap >r ( dest_end length dest cpy flag token flag R: s_end s_buf ) + swap >r ( dest_end length dest cpy flag flag R: s_end s_buf token ) + or if ( dest_end length dest cpy R: s_end s_buf token ) + + 3 pick over swap > if + " lz4 write beyond buffer end" die ( write beyond the dest end ) + then ( dest_end length dest cpy ) + + 2 pick ( dest_end length dest cpy length ) + r> r> swap ( dest_end length dest cpy length s_buf token R: s_end ) + r> ( dest_end length dest cpy length s_buf token s_end ) + swap >r >r ( dest_end length dest cpy length s_buf R: token s_end ) + + swap over + ( dest_end length dest cpy s_buf s_buf+length ) + r@ > if ( dest_end length dest cpy s_buf R: token s_end ) + " lz4 read beyond source" die \ read beyond source buffer + then + + nip ( dest_end length dest s_buf R: token s_end ) + >r ( dest_end length dest R: token s_end s_buf ) + over r@ ( dest_end length dest length s_buf ) + -rot move ( dest_end length ) + + r> + r> r> drop < if + " lz4 format violation" die \ LZ4 format violation + then + + r> drop \ drop original dest + drop + exit \ parsing done + then + + swap ( dest_end length cpy dest R: s_end s_buf token ) + r> r> swap >r ( dest_end length cpy dest s_buf R: s_end token ) + + lz4_copy ( dest_end length cpy dest s_buf) + + -rot ( dest_end length s_buf cpy dest ) + over - ( dest_end length s_buf cpy dest-cpy ) + rot ( dest_end length cpy dest-cpy s_buf ) + swap - ( dest_end length cpy s_buf ) + + dup C@ swap ( dest_end length cpy b s_buf ) + dup 1+ C@ 8 lshift ( dest_end length cpy b s_buf w ) + rot or ( dest_end length cpy s_buf w ) + 2 pick swap - ( dest_end length cpy s_buf ref ) + swap 2 + ( dest_end length cpy ref s_buf+2 ) + \ note: cpy is also dest, remember to save it + -rot ( dest_end length s_buf cpy ref ) + dup ( dest_end length s_buf cpy ref ref ) + + \ now we need original dest + r> r> swap r@ ( dest_end length s_buf cpy ref ref s_end token dest ) + -rot swap >r >r + < if + " lz4 reference outside buffer" die \ reference outside dest buffer + then ( dest_end length s_buf op ref ) + + 2swap ( dest_end op ref length s_buf ) + swap ( dest_end op ref s_buf length R: dest s_end token ) + + \ get matchlength + drop r> ML_MASK and ( dest_end op ref s_buf length R: dest s_end ) + dup ML_MASK = if ( dest_end op ref s_buf length R: dest s_end ) + -1 \ flag to top + begin + rot ( dest_end op ref length flag s_buf ) + dup r@ < ( dest_end op ref length flag s_buf flag ) + rot and ( dest_end op ref length s_buf flag ) + while + dup c@ ( dest_end op ref length s_buf s ) + swap 1+ ( dest_end op ref length s s_buf++ ) + -rot ( dest_end op ref s_buf length s ) + swap over + swap ( dest_end op ref s_buf length+s s ) + d# 255 = + repeat + swap + then ( dest_end op ref s_buf length R: dest s_end ) + + 2swap ( dest_end s_buf length op ref ) + + \ copy repeated sequence + 2dup - STEPSIZE < if ( dest_end s_buf length op ref ) + \ 4 times *op++ = *ref++; + dup c@ >r ( dest_end s_buf length op ref R: C ) + CHAR+ swap ( dest_end s_buf length ref++ op ) + dup r> swap c! CHAR+ swap ( dest_end s_buf length op ref ) + dup c@ >r ( dest_end s_buf length op ref R: C ) + CHAR+ swap ( dest_end s_buf length ref++ op ) + dup r> swap c! CHAR+ swap ( dest_end s_buf length op ref ) + dup c@ >r ( dest_end s_buf length op ref R: C ) + CHAR+ swap ( dest_end s_buf length ref++ op ) + dup r> swap c! CHAR+ swap ( dest_end s_buf length op ref ) + dup c@ >r ( dest_end s_buf length op ref R: C ) + CHAR+ swap ( dest_end s_buf length ref++ op ) + dup r> swap c! CHAR+ swap ( dest_end s_buf length op ref ) + 2dup - ( dest_end s_buf length op ref op-ref ) + case + 1 of 3 endof + 2 of 2 endof + 3 of 3 endof + 0 + endcase + - \ ref -= dec + 2dup swap 4 move ( dest_end s_buf length op ref ) + swap STEPSIZE 4 - + + swap ( dest_end s_buf length op ref ) + else + lz4_copystep ( dest_end s_buf length op ref ) + then + -rot ( dest_end s_buf ref length op ) + swap over ( dest_end s_buf ref op length op ) + + STEPSIZE 4 - - ( dest_end s_buf ref op cpy R: dest s_end ) + + \ if cpy > oend - COPYLENGTH + 4 pick COPYLENGTH - ( dest_end s_buf ref op cpy oend-COPYLENGTH ) + 2dup > if ( dest_end s_buf ref op cpy oend-COPYLENGTH ) + swap ( dest_end s_buf ref op oend-COPYLENGTH cpy ) + + 5 pick over < if + " lz4 write outside buffer" die \ write outside of dest buffer + then ( dest_end s_buf ref op oend-COPYLENGTH cpy ) + + >r ( dest_end s_buf ref op oend-COPYLENGTH R: dest s_end cpy ) + -rot swap ( dest_end s_buf oend-COPYLENGTH op ref ) + lz4_copy ( dest_end s_buf oend-COPYLENGTH op ref ) + rot drop swap r> ( dest_end s_buf ref op cpy ) + begin + 2dup < + while + >r ( dest_end s_buf ref op R: cpy ) + over ( dest_end s_buf ref op ref ) + c@ ( dest_end s_buf ref op C ) + over c! ( dest_end s_buf ref op ) + >r 1+ r> 1+ r> ( dest_end s_buf ref++ op++ cpy ) + repeat + + nip ( dest_end s_buf ref op ) + dup 4 pick = if + \ op == dest_end we are done, cleanup + r> r> 2drop 2drop 2drop + exit + then + ( dest_end s_buf ref op R: dest s_end ) + nip ( dest_end s_buf op ) + else + drop ( dest_end s_buf ref op cpy R: dest s_end) + -rot ( dest_end s_buf cpy ref op ) + swap ( dest_end s_buf cpy op ref ) + lz4_copy + 2drop ( dest_end s_buf op ) + then + + -rot r> ( op dest_end s_buf s_end R: dest ) + repeat + + r> drop + 2drop + 2drop + ; \ \ ZFS block (SPA) routines @@ -167,6 +421,7 @@ new-device 1 constant def-comp# 2 constant no-comp# 3 constant lzjb-comp# + d# 15 constant lz4-comp# h# 2.0000 constant /max-bsize d# 512 constant /disk-block @@ -254,16 +509,27 @@ new-device read-dva exit ( ) then - \ only do lzjb - dup blk_comp dup lzjb-comp# <> ( adr len bp comp lzjb? ) + \ lzjb? + dup blk_comp lzjb-comp# = if + \ read into blk-space and de-compress + blk-space over bp-dsize ( adr len bp blk-adr rd-len ) + rot read-dva ( adr len ) + blk-space -rot lzjb ( ) + exit + then + + dup blk_comp dup lz4-comp# <> ( adr len bp comp lz4? ) swap def-comp# <> and if ( adr len bp ) - " only lzjb supported" die + dup hex . ." BP: " + blk_comp decimal . + ." : bug, unknown compression algorithm: " + " only lzjb and lz4 supported" die then \ read into blk-space and de-compress blk-space over bp-dsize ( adr len bp blk-adr rd-len ) rot read-dva ( adr len ) - blk-space -rot lzjb ( ) + blk-space -rot lz4 ( ) ; \ -- 2.11.4.GIT