zfs.fth revision c713350eb0c205161e2a4ab06cd996300721ac78
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje\
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje\ CDDL HEADER START
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje\
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje\ The contents of this file are subject to the terms of the
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje\ Common Development and Distribution License (the "License").
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje\ You may not use this file except in compliance with the License.
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje\
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje\ You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje\ or http://www.opensolaris.org/os/licensing.
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje\ See the License for the specific language governing permissions
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje\ and limitations under the License.
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje\
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje\ When distributing Covered Code, include this CDDL HEADER in each
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje\ file and include the License file at usr/src/OPENSOLARIS.LICENSE.
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje\ If applicable, add the following below this CDDL HEADER, with the
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje\ fields enclosed by brackets "[]" replaced with your own identifying
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje\ information: Portions Copyright [yyyy] [name of copyright owner]
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje\
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje\ CDDL HEADER END
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje\
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje\
c713350eb0c205161e2a4ab06cd996300721ac78John Johnson\ Copyright 2009 Sun Microsystems, Inc. All rights reserved.
c713350eb0c205161e2a4ab06cd996300721ac78John Johnson\ Use is subject to license terms.
c713350eb0c205161e2a4ab06cd996300721ac78John Johnson\
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setjepurpose: ZFS file system support package
c713350eb0c205161e2a4ab06cd996300721ac78John Johnsoncopyright: Copyright 2009 Sun Microsystems, Inc. All Rights Reserved
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje" /packages" get-package push-package
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setjenew-device
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje fs-pkg$ device-name diag-cr?
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje 0 instance value temp-space
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje \ 64b ops
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje \ fcode is still 32b on 64b sparc-v9, so
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje \ we need to override some arithmetic ops
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje \ stack ops and logical ops (dup, and, etc) are 64b
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje : xcmp ( x1 x2 -- -1|0|1 )
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje xlsplit rot xlsplit ( x2.lo x2.hi x1.lo x1.hi )
e7cbe64f7a72dae5cb44f100db60ca88f3313c65gw rot 2dup u< if ( x2.lo x1.lo x1.hi x2.hi )
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje 2drop 2drop -1 ( lt )
e7cbe64f7a72dae5cb44f100db60ca88f3313c65gw else u> if ( x2.lo x1.lo )
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje 2drop 1 ( gt )
e7cbe64f7a72dae5cb44f100db60ca88f3313c65gw else swap 2dup u< if ( x1.lo x2.lo )
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje 2drop -1 ( lt )
e7cbe64f7a72dae5cb44f100db60ca88f3313c65gw else u> if ( )
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje 1 ( gt )
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje else ( )
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje 0 ( eq )
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje then then then then ( -1|0|1 )
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje ;
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje : x< ( x1 x2 -- <? ) xcmp -1 = ;
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje : x> ( x1 x2 -- >? ) xcmp 1 = ;
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje\ : x= ( x1 x2 -- =? ) xcmp 0= ;
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje : x<> ( x1 x2 -- <>? ) xcmp 0<> ;
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje : x0= ( x -- 0=? ) xlsplit 0= swap 0= and ;
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje /buf-len instance buffer: numbuf
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje : (xu.) ( u -- u$ )
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje numbuf /buf-len + swap ( adr u )
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje begin
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje d# 10 /mod swap ( adr u' rem )
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje ascii 0 + ( adr u' c )
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje rot 1- tuck c! ( u adr' )
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje swap dup 0= ( adr u done? )
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje until drop ( adr )
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje dup numbuf - /buf-len swap - ( adr len )
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje ;
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje \ pool name
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje /buf-len instance buffer: bootprop-buf
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje : bootprop$ ( -- prop$ ) bootprop-buf cscount ;
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje \ decompression
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje \
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje \ uts/common/os/compress.c has a definitive theory of operation comment
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje \ on lzjb, but here's the reader's digest version:
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje \
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje \ repeated phrases are replaced by referenced to the original
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje \ e.g.,
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje \ y a d d a _ y a d d a _ y a d d a , _ b l a h _ b l a h _ b l a h
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje \ becomes
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje \ y a d d a _ 6 11 , _ b l a h 5 10
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje \ where 6 11 means memmove(ptr, ptr - 6, 11)
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje \
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje \ data is separated from metadata with embedded copymap entries
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje \ every 8 items e.g.,
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje \ 0x40 y a d d a _ 6 11 , 0x20 _ b l a h 5 10
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje \ the copymap has a set bit for copy refercences
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje \ and a clear bit for bytes to be copied directly
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje \
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje \ the reference marks are encoded with match-bits and match-min
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje \ e.g.,
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje \ byte[0] = ((mlen - MATCH_MIN) << (NBBY - MATCH_BITS) | (off >> NBBY)
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje \ byte[1] = (uint8_t)off
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje \
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje : pow2 ( n -- 2**n ) 1 swap lshift ;
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje \ assume MATCH_BITS=6 and MATCH_MIN=3
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje 6 constant mbits
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje 3 constant mmin
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje 8 mbits - constant mshift
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje d# 16 mbits - pow2 1- constant mmask
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje : decode-src ( src -- mlen off )
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje dup c@ swap 1+ c@ ( c[0] c[1] )
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje over mshift rshift mmin + ( c[0] c[1] mlen )
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje -rot swap bwjoin mmask and ( mlen off )
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje ;
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje \ equivalent of memmove(dst, dst - off, len)
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje \ src points to a copy reference to be decoded
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje : mcopy ( dend dst src -- dend dst' )
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje decode-src ( dend dst mlen off )
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje 2 pick swap - >r ( dent dst mlen r: cpy )
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje begin
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje 1- dup 0>= ( dend dst mlen' any? r: cpy )
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje 2over > and ( dend dst mlen !done? r : cpy )
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje while ( dend dst mlen r: cpy )
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje swap r> dup 1+ >r c@ ( dend mlen dst c r: cpy' )
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje over c! 1+ swap ( dend dst' mlen r: cpy )
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje repeat ( dend dst' mlen r: cpy )
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje r> 2drop ( dend dst )
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje ;
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje : lzjb ( src dst len -- )
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje over + swap ( src dend dst )
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje rot >r ( dend dst r: src )
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje \ setup mask so 1st while iteration fills map
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje 0 7 pow2 2swap ( map mask dend dst r: src )
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje begin 2dup > while
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje 2swap 1 lshift ( dend dst map mask' r: src )
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje dup 8 pow2 = if
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje \ fetch next copymap
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje 2drop ( dend dst r: src )
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje r> dup 1+ >r c@ 1 ( dend dst map' mask' r: src' )
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje then ( dend dst map mask r: src' )
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje \ if (map & mask) we hit a copy reference
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje \ else just copy 1 byte
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje 2swap 2over and if ( map mask dend dst r: src )
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje r> dup 2+ >r ( map mask dend dst src r: src' )
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje mcopy ( map mask dend dst' r: src )
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje else
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje r> dup 1+ >r c@ ( map mask dend dst c r: src' )
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje over c! 1+ ( map mask dend dst' r: src )
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje then
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje repeat ( map mask dend dst r: src )
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje 2drop 2drop r> drop ( )
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje ;
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje \
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje \ ZFS block (SPA) routines
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje \
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje
c713350eb0c205161e2a4ab06cd996300721ac78John Johnson 1 constant def-comp#
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje 2 constant no-comp#
c713350eb0c205161e2a4ab06cd996300721ac78John Johnson 3 constant lzjb-comp#
c713350eb0c205161e2a4ab06cd996300721ac78John Johnson
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje h# 2.0000 constant /max-bsize
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje d# 512 constant /disk-block
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje d# 128 constant /blkp
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje
c713350eb0c205161e2a4ab06cd996300721ac78John Johnson alias /gang-block /disk-block
c713350eb0c205161e2a4ab06cd996300721ac78John Johnson
c713350eb0c205161e2a4ab06cd996300721ac78John Johnson \ the ending checksum is larger than 1 byte, but that
c713350eb0c205161e2a4ab06cd996300721ac78John Johnson \ doesn't affect the math here
c713350eb0c205161e2a4ab06cd996300721ac78John Johnson /gang-block 1-
c713350eb0c205161e2a4ab06cd996300721ac78John Johnson /blkp / constant #blks/gang
c713350eb0c205161e2a4ab06cd996300721ac78John Johnson
c713350eb0c205161e2a4ab06cd996300721ac78John Johnson : blk_offset ( bp -- n ) h# 8 + x@ -1 h# 7fff.ffff lxjoin and ;
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje : blk_gang ( bp -- n ) h# 8 + x@ xlsplit nip d# 31 rshift ;
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje : blk_comp ( bp -- n ) h# 33 + c@ ;
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje : blk_psize ( bp -- n ) h# 34 + w@ ;
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje : blk_lsize ( bp -- n ) h# 36 + w@ ;
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje : blk_birth ( bp -- n ) h# 50 + x@ ;
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje 0 instance value dev-ih
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje 0 instance value blk-space
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje 0 instance value gang-space
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje : foff>doff ( fs-off -- disk-off ) /disk-block * h# 40.0000 + ;
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje : fsz>dsz ( fs-size -- disk-size ) 1+ /disk-block * ;
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje : bp-dsize ( bp -- dsize ) blk_psize fsz>dsz ;
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje : bp-lsize ( bp -- lsize ) blk_lsize fsz>dsz ;
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje
c713350eb0c205161e2a4ab06cd996300721ac78John Johnson : (read-dva) ( adr len dva -- )
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje blk_offset foff>doff dev-ih read-disk
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje ;
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje
c713350eb0c205161e2a4ab06cd996300721ac78John Johnson : gang-read ( adr len bp gb-adr -- ) tokenizer[ reveal ]tokenizer
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje \ read gang block
c713350eb0c205161e2a4ab06cd996300721ac78John Johnson tuck /gang-block rot (read-dva) ( adr len gb-adr )
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje
c713350eb0c205161e2a4ab06cd996300721ac78John Johnson \ loop through indirected bp's
c713350eb0c205161e2a4ab06cd996300721ac78John Johnson dup /blkp #blks/gang * ( adr len gb-adr bp-list bp-list-len )
c713350eb0c205161e2a4ab06cd996300721ac78John Johnson bounds do ( adr len gb-adr )
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje i blk_offset x0= ?leave
c713350eb0c205161e2a4ab06cd996300721ac78John Johnson
c713350eb0c205161e2a4ab06cd996300721ac78John Johnson \ calc subordinate read len
c713350eb0c205161e2a4ab06cd996300721ac78John Johnson over i bp-dsize min ( adr len gb-adr sub-len )
c713350eb0c205161e2a4ab06cd996300721ac78John Johnson 2swap swap ( gb-adr sub-len len adr )
c713350eb0c205161e2a4ab06cd996300721ac78John Johnson
c713350eb0c205161e2a4ab06cd996300721ac78John Johnson \ nested gang block - recurse with new gang block area
c713350eb0c205161e2a4ab06cd996300721ac78John Johnson i blk_gang if
c713350eb0c205161e2a4ab06cd996300721ac78John Johnson 2swap ( len adr gb-adr sub-len )
c713350eb0c205161e2a4ab06cd996300721ac78John Johnson 3dup swap /gang-block + ( len adr gb-adr sub-len adr sub-len gb-adr' )
c713350eb0c205161e2a4ab06cd996300721ac78John Johnson i swap gang-read ( len adr gb-adr sub-len )
c713350eb0c205161e2a4ab06cd996300721ac78John Johnson 2swap ( gb-adr sub-len len adr )
c713350eb0c205161e2a4ab06cd996300721ac78John Johnson else
c713350eb0c205161e2a4ab06cd996300721ac78John Johnson 3dup nip swap ( gb-adr sub-len len adr adr sub-len )
c713350eb0c205161e2a4ab06cd996300721ac78John Johnson i (read-dva) ( gb-adr sub-len len adr )
c713350eb0c205161e2a4ab06cd996300721ac78John Johnson then ( gb-adr sub-len len adr )
c713350eb0c205161e2a4ab06cd996300721ac78John Johnson
c713350eb0c205161e2a4ab06cd996300721ac78John Johnson \ adjust adr,len and check if done
c713350eb0c205161e2a4ab06cd996300721ac78John Johnson -rot over - ( gb-adr adr sub-len len' )
c713350eb0c205161e2a4ab06cd996300721ac78John Johnson -rot + swap ( gb-adr adr' len' )
c713350eb0c205161e2a4ab06cd996300721ac78John Johnson dup 0= ?leave
c713350eb0c205161e2a4ab06cd996300721ac78John Johnson rot ( adr' len' gb-adr )
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje /blkp +loop
c713350eb0c205161e2a4ab06cd996300721ac78John Johnson 3drop ( )
c713350eb0c205161e2a4ab06cd996300721ac78John Johnson ;
c713350eb0c205161e2a4ab06cd996300721ac78John Johnson
c713350eb0c205161e2a4ab06cd996300721ac78John Johnson : read-dva ( adr len dva -- )
c713350eb0c205161e2a4ab06cd996300721ac78John Johnson dup blk_gang if
c713350eb0c205161e2a4ab06cd996300721ac78John Johnson gang-space gang-read
c713350eb0c205161e2a4ab06cd996300721ac78John Johnson else
c713350eb0c205161e2a4ab06cd996300721ac78John Johnson (read-dva)
c713350eb0c205161e2a4ab06cd996300721ac78John Johnson then
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje ;
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje \ block read that check for holes, gangs, compression, etc
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje : read-bp ( adr len bp -- )
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje \ sparse block?
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje dup blk_birth x0= if
c713350eb0c205161e2a4ab06cd996300721ac78John Johnson drop erase exit ( )
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje then
c713350eb0c205161e2a4ab06cd996300721ac78John Johnson
c713350eb0c205161e2a4ab06cd996300721ac78John Johnson \ no compression?
c713350eb0c205161e2a4ab06cd996300721ac78John Johnson dup blk_comp no-comp# = if
c713350eb0c205161e2a4ab06cd996300721ac78John Johnson read-dva exit ( )
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje then
c713350eb0c205161e2a4ab06cd996300721ac78John Johnson
c713350eb0c205161e2a4ab06cd996300721ac78John Johnson \ only do lzjb
c713350eb0c205161e2a4ab06cd996300721ac78John Johnson dup blk_comp dup lzjb-comp# <> ( adr len bp comp lzjb? )
c713350eb0c205161e2a4ab06cd996300721ac78John Johnson swap def-comp# <> and if ( adr len bp )
c713350eb0c205161e2a4ab06cd996300721ac78John Johnson " only lzjb supported" die
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje then
c713350eb0c205161e2a4ab06cd996300721ac78John Johnson
c713350eb0c205161e2a4ab06cd996300721ac78John Johnson \ read into blk-space and de-compress
c713350eb0c205161e2a4ab06cd996300721ac78John Johnson blk-space over bp-dsize ( adr len bp blk-adr rd-len )
c713350eb0c205161e2a4ab06cd996300721ac78John Johnson rot read-dva ( adr len )
c713350eb0c205161e2a4ab06cd996300721ac78John Johnson blk-space -rot lzjb ( )
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje ;
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje \
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje \ ZFS vdev routines
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje \
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje h# 1.c000 constant /nvpairs
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje h# 4000 constant nvpairs-off
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje \
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje \ xdr packed nvlist
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje \
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje \ 12B header
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje \ array of xdr packed nvpairs
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje \ 4B encoded nvpair size
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje \ 4B decoded nvpair size
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje \ 4B name string size
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje \ name string
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje \ 4B data type
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje \ 4B # of data elements
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje \ data
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje \ 8B of 0
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje \
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje d# 12 constant /nvhead
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje : >nvsize ( nv -- size ) l@ ;
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje : >nvname ( nv -- name$ )
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje /l 2* + dup /l + swap l@
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje ;
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje : >nvdata ( nv -- data )
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje >nvname + /l roundup
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje ;
e7cbe64f7a72dae5cb44f100db60ca88f3313c65gw
e7cbe64f7a72dae5cb44f100db60ca88f3313c65gw \ convert nvdata to 64b int or string
e7cbe64f7a72dae5cb44f100db60ca88f3313c65gw : nvdata>x ( nvdata -- x )
e7cbe64f7a72dae5cb44f100db60ca88f3313c65gw /l 2* + ( ptr )
e7cbe64f7a72dae5cb44f100db60ca88f3313c65gw dup /l + l@ swap l@ ( x.lo x.hi )
e7cbe64f7a72dae5cb44f100db60ca88f3313c65gw lxjoin ( x )
e7cbe64f7a72dae5cb44f100db60ca88f3313c65gw ;
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje alias nvdata>$ >nvname
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje : nv-lookup ( nv name$ -- nvdata false | true )
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje rot /nvhead + ( name$ nvpair )
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje begin dup >nvsize while
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje dup >r >nvname ( name$ nvname$ r: nvpair )
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje 2over $= if ( name$ r: nvpair )
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje 2drop r> >nvdata ( nvdata )
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje false exit ( nvdata found )
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje then ( name$ r: nvpair )
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje r> dup >nvsize + ( name$ nvpair' )
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje repeat
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje 3drop true ( not-found )
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje ;
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje : scan-vdev ( -- )
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje temp-space /nvpairs nvpairs-off ( adr len off )
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje dev-ih read-disk ( )
e7cbe64f7a72dae5cb44f100db60ca88f3313c65gw temp-space " txg" nv-lookup if
e7cbe64f7a72dae5cb44f100db60ca88f3313c65gw " no txg nvpair" die
e7cbe64f7a72dae5cb44f100db60ca88f3313c65gw then nvdata>x ( txg )
e7cbe64f7a72dae5cb44f100db60ca88f3313c65gw x0= if
e7cbe64f7a72dae5cb44f100db60ca88f3313c65gw " detached mirror" die
e7cbe64f7a72dae5cb44f100db60ca88f3313c65gw then ( )
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje temp-space " name" nv-lookup if
e7cbe64f7a72dae5cb44f100db60ca88f3313c65gw " no name nvpair" die
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje then nvdata>$ ( pool$ )
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje bootprop-buf swap move ( )
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje ;
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje \
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje \ ZFS ueber-block routines
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje \
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje d# 1024 constant /uber-block
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje d# 128 constant #ub/label
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje #ub/label /uber-block * constant /ub-ring
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje h# 2.0000 constant ubring-off
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje : ub_magic ( ub -- n ) x@ ;
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje : ub_txg ( ub -- n ) h# 10 + x@ ;
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje : ub_timestamp ( ub -- n ) h# 20 + x@ ;
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje : ub_rootbp ( ub -- p ) h# 28 + ;
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje 0 instance value uber-block
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje : ub-cmp ( ub1 ub2 -- best-ub )
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje \ ub1 wins if ub2 isn't valid
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje dup ub_magic h# 00bab10c x<> if
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje drop exit ( ub1 )
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje then
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje \ if ub1 is 0, ub2 wins by default
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje over 0= if nip exit then ( ub2 )
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje \ 2 valid ubs, compare transaction groups
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje over ub_txg over ub_txg ( ub1 ub2 txg1 txg2 )
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje 2dup x< if
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje 2drop nip exit ( ub2 )
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje then ( ub1 ub2 txg1 txg2 )
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje x> if drop exit then ( ub1 )
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje \ same txg, check timestamps
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje over ub_timestamp over ub_timestamp x> if
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje nip ( ub2 )
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje else
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje drop ( ub1 )
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje then
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje ;
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje \ find best uber-block in ring, and copy it to uber-block
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje : get-ub ( -- )
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje temp-space /ub-ring ubring-off ( adr len off )
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje dev-ih read-disk ( )
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje 0 temp-space /ub-ring ( null-ub adr len )
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje bounds do ( ub )
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje i ub-cmp ( best-ub )
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje /uber-block +loop
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje \ make sure we found a valid ub
e7cbe64f7a72dae5cb44f100db60ca88f3313c65gw dup 0= if " no ub found" die then
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje uber-block /uber-block move ( )
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje ;
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje \
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje \ ZFS dnode (DMU) routines
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje \
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje d# 512 constant /dnode
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje : dn_indblkshift ( dn -- n ) h# 1 + c@ ;
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje : dn_nlevels ( dn -- n ) h# 2 + c@ ;
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje : dn_datablkszsec ( dn -- n ) h# 8 + w@ ;
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje : dn_blkptr ( dn -- p ) h# 40 + ;
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje : dn_bonus ( dn -- p ) h# c0 + ;
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje 0 instance value dnode
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje \ indirect cache
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje \
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje \ ind-cache is a 1 block indirect block cache from dnode ic-dn
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje \
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje \ ic-bp and ic-bplim point into the ic-dn's block ptr array,
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje \ either in dn_blkptr or in ind-cache ic-bp is the ic-blk#'th
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje \ block ptr, and ic-bplim is limit of the current bp array
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje \
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje \ the assumption is that reads will be sequential, so we can
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje \ just increment ic-bp
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje \
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje 0 instance value ind-cache
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje 0 instance value ic-dn
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje 0 instance value ic-blk#
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje 0 instance value ic-bp
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje 0 instance value ic-bplim
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje : dn-bsize ( dn -- bsize ) dn_datablkszsec /disk-block * ;
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje : dn-indsize ( dn -- indsize ) dn_indblkshift pow2 ;
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje : dn-indmask ( dn -- mask ) dn-indsize 1- ;
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje \ recursively climb the block tree from the leaf to the root
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje : blk@lvl>bp ( dn blk# lvl -- bp ) tokenizer[ reveal ]tokenizer
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje >r /blkp * over dn_nlevels ( dn bp-off #lvls r: lvl )
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje \ at top, just add dn_blkptr
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje r@ = if ( dn bp-off r: lvl )
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje swap dn_blkptr + ( bp r: lvl )
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje r> drop exit ( bp )
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje then ( dn bp-off r: lvl )
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje \ shift bp-off down and find parent indir blk
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje 2dup over dn_indblkshift rshift ( dn bp-off dn blk# r: lvl )
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje r> 1+ blk@lvl>bp ( dn bp-off bp )
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje
e7cbe64f7a72dae5cb44f100db60ca88f3313c65gw \ read parent indir blk and index
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje rot tuck dn-indsize ( bp-off dn bp len )
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje ind-cache swap rot read-bp ( bp-off dn )
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje dn-indmask and ( bp-off' )
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje ind-cache + ( bp )
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje ;
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje \ return end of current bp array
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje : bplim ( dn bp -- bp-lim )
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje over dn_nlevels 1 = if
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje drop dn_blkptr ( bp0 )
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje 3 /blkp * + ( bplim )
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje else
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje 1+ swap dn-indsize ( bp+1 indsz )
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje roundup ( bplim )
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje then
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje ;
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje \ return the lblk#'th block ptr from dnode
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje : lblk#>bp ( dn blk# -- bp )
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje 2dup ( dn blk# dn blk# )
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje ic-blk# <> swap ic-dn <> or ( dn blk# cache-miss? )
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje ic-bp ic-bplim = ( dn blk# cache-miss? cache-empty? )
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje or if ( dn blk# )
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje 2dup 1 blk@lvl>bp ( dn blk# bp )
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje dup to ic-bp ( dn blk# bp )
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje swap to ic-blk# ( dn bp )
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje 2dup bplim to ic-bplim ( dn bp )
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje over to ic-dn
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje then 2drop ( )
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje ic-blk# 1+ to ic-blk#
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje ic-bp dup /blkp + to ic-bp ( bp )
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje ;
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje \
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje \ ZFS attribute (ZAP) routines
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje \
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje 1 constant fzap#
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje 3 constant uzap#
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje d# 64 constant /uzap
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje d# 24 constant /lf-chunk
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje d# 21 constant /lf-arr
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje h# ffff constant chain-end#
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje h# 100 constant /lf-buf
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje /lf-buf instance buffer: leaf-value
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje /lf-buf instance buffer: leaf-name
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje : +le ( len off -- n ) + w@ ;
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje : le_next ( le -- n ) h# 2 +le ;
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje : le_name_chunk ( le -- n ) h# 4 +le ;
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje : le_name_length ( le -- n ) h# 6 +le ;
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje : le_value_chunk ( le -- n ) h# 8 +le ;
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje : le_value_length ( le -- n ) h# a +le ;
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje : la_array ( la -- adr ) 1+ ;
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje : la_next ( la -- n ) h# 16 + w@ ;
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje 0 instance value zap-space
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje \ setup leaf hash bounds
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje : >leaf-hash ( dn lh -- hash-adr /hash )
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje /lf-chunk 2* + ( dn hash-adr )
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje \ size = (bsize / 32) * 2
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje swap dn-bsize 4 rshift ( hash-adr /hash )
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje ;
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje : >leaf-chunks ( lf -- ch0 ) >leaf-hash + ;
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje \ convert chunk # to leaf chunk
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje : ch#>lc ( dn ch# -- lc )
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje /lf-chunk * ( dn lc-off )
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje swap zap-space >leaf-chunks ( lc-off ch0 )
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje + ( lc )
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje ;
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje \ assemble chunk chain into single buffer
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje : get-chunk-data ( dn ch# adr -- )
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje dup >r /lf-buf erase ( dn ch# r: adr )
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje begin
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje 2dup ch#>lc nip ( dn la r: adr )
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje dup la_array ( dn la la-arr r: adr )
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje r@ /lf-arr move ( dn la r: adr )
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje r> /lf-arr + >r ( dn la r: adr' )
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje la_next dup chain-end# = ( dn la-ch# end? r: adr )
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje until r> 3drop ( )
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje ;
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje \ get leaf entry's name
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje : entry-name$ ( dn le -- name$ )
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje 2dup le_name_chunk ( dn le dn la-ch# )
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje leaf-name get-chunk-data ( dn le )
b8b2ae86d7bf3651ade08dc386dbd2317d3e1febjgj nip le_name_length 1- ( len )
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje leaf-name swap ( name$ )
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje ;
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje \ return entry value as int
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje : entry-int-val ( dn le -- n )
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje le_value_chunk ( dn la-ch# )
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje leaf-value get-chunk-data ( )
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje leaf-value x@ ( n )
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje ;
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje[ifdef] strlookup
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje \ get leaf entry's value as string
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje : entry-val$ ( dn le -- val$ )
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje 2dup le_value_chunk ( dn le dn la-ch# )
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje leaf-value get-chunk-data ( dn le )
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje nip le_value_length ( len )
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje leaf-value swap ( name$ )
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje ;
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje[then]
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje \ apply xt to entry
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje : entry-apply ( xt dn le -- xt dn false | ??? true )
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje over >r ( xt dn le r: dn )
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje rot dup >r execute if ( ??? r: xt dn )
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje r> r> 2drop true ( ??? true )
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje else ( )
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje r> r> false ( xt dn false )
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje then
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje ;
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje \ apply xt to every entry in chain
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje : chain-apply ( xt dn ch# -- xt dn false | ??? true )
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje begin
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje 2dup ch#>lc nip ( xt dn le )
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje dup >r entry-apply if ( ??? r: le )
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje r> drop true exit ( ??? found )
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje then ( xt dn r: le )
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje r> le_next ( xt dn ch# )
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje dup chain-end# = ( xt dn ch# end? )
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje until drop ( xt dn )
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje false ( xt dn false )
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje ;
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje \ apply xt to every entry in leaf
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje : leaf-apply ( xt dn blk# -- xt dn false | ??? true )
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje \ read zap leaf into zap-space
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje 2dup lblk#>bp ( xt dn blk# bp )
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje nip over dn-bsize zap-space ( xt dn bp len adr )
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje swap rot read-bp ( xt dn )
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje \ call chunk-look for every valid chunk list
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje dup zap-space >leaf-hash ( xt dn hash-adr /hash )
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje bounds do ( xt dn )
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje i w@ dup chain-end# <> if ( xt dn ch# )
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje chain-apply if ( ??? )
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje unloop true exit ( ??? found )
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje then ( xt dn )
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje else drop then ( xt dn )
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje /w +loop
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje false ( xt dn not-found )
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje ;
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje \ apply xt to every entry in fzap
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje : fzap-apply ( xt dn fz -- ??? not-found? )
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje \ blk# 1 is always the 1st leaf
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje >r 1 leaf-apply if ( ??? r: fz )
b8b2ae86d7bf3651ade08dc386dbd2317d3e1febjgj r> drop true exit ( ??? found )
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje then r> ( xt dn fz )
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje \ call leaf-apply on every non-duplicate hash entry
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje \ embedded hash is in 2nd half of fzap block
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje over dn-bsize tuck + ( xt dn bsize hash-eadr )
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje swap 2dup 2/ - ( xt dn hash-eadr bsize hash-adr )
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje nip do ( xt dn )
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje i x@ dup 1 <> if ( xt dn blk# )
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje leaf-apply if ( ??? )
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje unloop true exit ( ??? found )
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje then ( xt dn )
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje else drop then ( xt dn )
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje /x +loop
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje 2drop false ( not-found )
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje ;
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje : mze_value ( uz -- n ) x@ ;
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje : mze_name ( uz -- p ) h# e + ;
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje : uzap-name$ ( uz -- name$ ) mze_name cscount ;
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje \ apply xt to each entry in micro-zap
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje : uzap-apply ( xt uz len -- ??? not-found? )
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje bounds do ( xt )
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje i swap dup >r ( uz xt r: xt )
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje execute if ( ??? r: xt )
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje r> drop ( ??? )
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje unloop true exit ( ??? found )
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje then r> ( xt )
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje /uzap +loop
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje drop false ( not-found )
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje ;
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje \ match by name
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje : fz-nmlook ( prop$ dn le -- prop$ false | prop$ dn le true )
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje 2dup entry-name$ ( prop$ dn le name$ )
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje 2rot 2swap ( dn le prop$ name$ )
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje 2over $= if ( dn le prop$ )
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje 2swap true ( prop$ dn le true )
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje else ( dn le prop$ )
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje 2swap 2drop false ( prop$ false )
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje then ( prop$ false | prop$ dn le true )
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje ;
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje \ match by name
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje : uz-nmlook ( prop$ uz -- prop$ false | prop$ uz true )
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje dup >r uzap-name$ ( prop$ name$ r: uz )
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje 2over $= if ( prop$ r: uz )
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje r> true ( prop$ uz true )
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje else ( prop$ r: uz )
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje r> drop false ( prop$ false )
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje then ( prop$ false | prop$ uz true )
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje ;
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje : zap-type ( zp -- n ) h# 7 + c@ ;
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje : >uzap-ent ( adr -- ent ) h# 40 + ;
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje \ read zap block into temp-space
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje : get-zap ( dn -- zp )
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje dup 0 lblk#>bp ( dn bp )
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje swap dn-bsize ( bp len )
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje temp-space swap ( bp adr len )
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje rot read-bp ( )
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje temp-space ( zp )
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje ;
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje \ find prop in zap dnode
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje : zap-lookup ( dn prop$ -- [ n ] not-found? )
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje rot dup get-zap ( prop$ dn zp )
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje dup zap-type case
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje uzap# of
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje >uzap-ent swap dn-bsize ( prop$ uz len )
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje ['] uz-nmlook -rot ( prop$ xt uz len )
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje uzap-apply if ( prop$ uz )
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje mze_value -rot 2drop ( n )
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje false ( n found )
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje else ( prop$ )
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje 2drop true ( !found )
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje then ( [ n ] not-found? )
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje endof
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje fzap# of
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje ['] fz-nmlook -rot ( prop$ xt dn fz )
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje fzap-apply if ( prop$ dn le )
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje entry-int-val ( prop$ n )
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje -rot 2drop false ( n found )
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje else ( prop$ )
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje 2drop true ( !found )
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje then ( [ n ] not-found? )
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje endof
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje 3drop 2drop true ( !found )
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje endcase ( [ n ] not-found? )
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje ;
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje[ifdef] strlookup
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje : zap-lookup-str ( dn prop$ -- [ val$ ] not-found? )
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje rot dup get-zap ( prop$ dn zp )
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje dup zap-type fzap# <> if ( prop$ dn zp )
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje 2drop 2drop true exit ( !found )
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje then ( prop$ dn zp )
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje ['] fz-nmlook -rot ( prop$ xt dn fz )
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje fzap-apply if ( prop$ dn le )
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje entry-val$ 2swap 2drop false ( val$ found )
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje else ( prop$ )
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje 2drop true ( !found )
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje then ( [ val$ ] not-found? )
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje ;
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje[then]
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje : fz-print ( dn le -- false )
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje entry-name$ type cr false
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje ;
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje : uz-print ( uz -- false )
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje uzap-name$ type cr false
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje ;
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje : zap-print ( dn -- )
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje dup get-zap ( dn zp )
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje dup zap-type case
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje uzap# of
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje >uzap-ent swap dn-bsize ( uz len )
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje ['] uz-print -rot ( xt uz len )
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje uzap-apply ( false )
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje endof
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje fzap# of
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje ['] fz-print -rot ( xt dn fz )
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje fzap-apply ( false )
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje endof
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje 3drop false ( false )
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje endcase ( false )
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje drop ( )
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje ;
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje \
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje \ ZFS object set (DSL) routines
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje \
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje 1 constant pool-dir#
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje : dd_head_dataset_obj ( dd -- n ) h# 8 + x@ ;
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje : dd_child_dir_zapobj ( dd -- n ) h# 20 + x@ ;
e7cbe64f7a72dae5cb44f100db60ca88f3313c65gw
e7cbe64f7a72dae5cb44f100db60ca88f3313c65gw : ds_snapnames_zapobj ( ds -- n ) h# 20 + x@ ;
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje : ds_bp ( ds -- p ) h# 80 + ;
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje 0 instance value mos-dn
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje 0 instance value obj-dir
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje 0 instance value root-dsl
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje 0 instance value root-dsl#
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje 0 instance value fs-dn
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje \ dn-cache contains dc-dn's contents at dc-blk#
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje \ dc-dn will be either mos-dn or fs-dn
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje 0 instance value dn-cache
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje 0 instance value dc-dn
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje 0 instance value dc-blk#
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje alias >dsl-dir dn_bonus
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje alias >dsl-ds dn_bonus
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje
e7cbe64f7a72dae5cb44f100db60ca88f3313c65gw : #dn/blk ( dn -- n ) dn-bsize /dnode / ;
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje \ read block into dn-cache
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje : get-dnblk ( dn blk# -- )
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje lblk#>bp dn-cache swap ( adr bp )
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje dup bp-lsize swap read-bp ( )
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje ;
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje \ read obj# from objset dir dn into dnode
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje : get-dnode ( dn obj# -- )
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje \ check dn-cache
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje 2dup swap #dn/blk /mod ( dn obj# off# blk# )
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje swap >r nip ( dn blk# r: off# )
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje 2dup dc-blk# <> ( dn blk# dn !blk-hit? r: off# )
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje swap dc-dn <> or if ( dn blk# r: off# )
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje \ cache miss, fill from dir
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje 2dup get-dnblk
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje over to dc-dn
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje dup to dc-blk#
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje then ( dn blk# r: off# )
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje \ index and copy
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje 2drop r> /dnode * ( off )
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje dn-cache + ( dn-adr )
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje dnode /dnode move ( )
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje ;
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje \ read meta object set from uber-block
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje : get-mos ( -- )
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje mos-dn /dnode ( adr len )
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje uber-block ub_rootbp read-bp
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje ;
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje : get-mos-dnode ( obj# -- )
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje mos-dn swap get-dnode
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje ;
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje \ get root dataset
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje : get-root-dsl ( -- )
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje \ read MOS
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje get-mos
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje \ read object dir
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje pool-dir# get-mos-dnode
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje dnode obj-dir /dnode move
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje \ read root dataset
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje obj-dir " root_dataset" zap-lookup if
e7cbe64f7a72dae5cb44f100db60ca88f3313c65gw " no root_dataset" die
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje then ( obj# )
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje dup to root-dsl#
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje get-mos-dnode ( )
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje dnode root-dsl /dnode move
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje ;
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje
e7cbe64f7a72dae5cb44f100db60ca88f3313c65gw \ find snapshot of given dataset
e7cbe64f7a72dae5cb44f100db60ca88f3313c65gw : snap-look ( snap$ ds-obj# -- [ss-obj# ] not-found? )
e7cbe64f7a72dae5cb44f100db60ca88f3313c65gw get-mos-dnode dnode >dsl-ds ( snap$ ds )
e7cbe64f7a72dae5cb44f100db60ca88f3313c65gw ds_snapnames_zapobj get-mos-dnode ( snap$ )
e7cbe64f7a72dae5cb44f100db60ca88f3313c65gw dnode -rot zap-lookup ( [ss-obj# ] not-found? )
e7cbe64f7a72dae5cb44f100db60ca88f3313c65gw ;
e7cbe64f7a72dae5cb44f100db60ca88f3313c65gw
e7cbe64f7a72dae5cb44f100db60ca88f3313c65gw \ dsl dir to dataset
e7cbe64f7a72dae5cb44f100db60ca88f3313c65gw : dir>ds ( dn -- obj# ) >dsl-dir dd_head_dataset_obj ;
e7cbe64f7a72dae5cb44f100db60ca88f3313c65gw
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje \ look thru the dsl hierarchy for path
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje \ this looks almost exactly like a FS directory lookup
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje : dsl-lookup ( path$ -- [ ds-obj# ] not-found? )
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje root-dsl >r ( path$ r: root-dn )
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje begin
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje ascii / left-parse-string ( path$ file$ r: dn )
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje dup while
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje \ get child dir zap dnode
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje r> >dsl-dir dd_child_dir_zapobj ( path$ file$ obj# )
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje get-mos-dnode ( path$ file$ )
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje
e7cbe64f7a72dae5cb44f100db60ca88f3313c65gw \ check for snapshot names
e7cbe64f7a72dae5cb44f100db60ca88f3313c65gw ascii @ left-parse-string ( path$ snap$ file$ )
e7cbe64f7a72dae5cb44f100db60ca88f3313c65gw
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje \ search it
e7cbe64f7a72dae5cb44f100db60ca88f3313c65gw dnode -rot zap-lookup if ( path$ snap$ )
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje \ not found
e7cbe64f7a72dae5cb44f100db60ca88f3313c65gw 2drop 2drop true exit ( not-found )
e7cbe64f7a72dae5cb44f100db60ca88f3313c65gw then ( path$ snap$ obj# )
e7cbe64f7a72dae5cb44f100db60ca88f3313c65gw get-mos-dnode ( path$ snap$ )
e7cbe64f7a72dae5cb44f100db60ca88f3313c65gw
e7cbe64f7a72dae5cb44f100db60ca88f3313c65gw \ lookup any snapshot name
e7cbe64f7a72dae5cb44f100db60ca88f3313c65gw dup if
e7cbe64f7a72dae5cb44f100db60ca88f3313c65gw \ must be last path component
e7cbe64f7a72dae5cb44f100db60ca88f3313c65gw 2swap nip if ( snap$ )
e7cbe64f7a72dae5cb44f100db60ca88f3313c65gw 2drop true exit ( not-found )
e7cbe64f7a72dae5cb44f100db60ca88f3313c65gw then
e7cbe64f7a72dae5cb44f100db60ca88f3313c65gw dnode dir>ds snap-look if ( )
e7cbe64f7a72dae5cb44f100db60ca88f3313c65gw true exit ( not-found )
e7cbe64f7a72dae5cb44f100db60ca88f3313c65gw then ( obj# )
e7cbe64f7a72dae5cb44f100db60ca88f3313c65gw false exit ( obj# found )
e7cbe64f7a72dae5cb44f100db60ca88f3313c65gw else 2drop then ( path$ )
e7cbe64f7a72dae5cb44f100db60ca88f3313c65gw
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje dnode >r ( path$ r: dn )
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje repeat ( path$ file$ r: dn)
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje 2drop 2drop r> drop ( )
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje \ found it, return dataset obj#
e7cbe64f7a72dae5cb44f100db60ca88f3313c65gw dnode dir>ds ( ds-obj# )
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje false ( ds-obj# found )
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje ;
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje \ get objset from dataset
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje : get-objset ( adr dn -- )
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje >dsl-ds ds_bp /dnode swap read-bp
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje ;
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje \
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje \ ZFS file-system (ZPL) routines
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje \
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje 1 constant master-node#
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje d# 264 constant /znode
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje d# 56 constant /zn-slink
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje : zp_mode ( zn -- n ) h# 48 + x@ ;
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje : zp_size ( zn -- n ) h# 50 + x@ ;
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje : zp_parent ( zn -- n ) h# 58 + x@ ;
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje 0 instance value bootfs-obj#
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje 0 instance value root-obj#
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje 0 instance value current-obj#
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje 0 instance value search-obj#
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje alias >znode dn_bonus
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje : fsize ( dn -- n ) >znode zp_size ;
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje : ftype ( dn -- n ) >znode zp_mode h# f000 and ;
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje : dir? ( dn -- flag ) ftype h# 4000 = ;
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje : symlink? ( dn -- flag ) ftype h# a000 = ;
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje \ read obj# from fs objset
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje : get-fs-dnode ( obj# -- )
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje dup to current-obj#
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje fs-dn swap get-dnode ( )
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje ;
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje \ get root-obj# from dataset
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje : get-rootobj# ( ds-obj# -- fsroot-obj# )
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje dup to bootfs-obj#
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje get-mos-dnode ( )
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje fs-dn dnode get-objset
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje \ get root obj# from master node
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje master-node# get-fs-dnode
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje dnode " ROOT" zap-lookup if
e7cbe64f7a72dae5cb44f100db60ca88f3313c65gw " no ROOT" die
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje then ( fsroot-obj# )
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje ;
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje : prop>rootobj# ( -- )
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje obj-dir " pool_props" zap-lookup if
e7cbe64f7a72dae5cb44f100db60ca88f3313c65gw " no pool_props" die
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje then ( prop-obj# )
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje get-mos-dnode ( )
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje dnode " bootfs" zap-lookup if
e7cbe64f7a72dae5cb44f100db60ca88f3313c65gw " no bootfs" die
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje then ( ds-obj# )
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje get-rootobj# ( fsroot-obj# )
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje ;
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje : fs>rootobj# ( fs$ -- root-obj# not-found? )
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje \ skip pool name
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje ascii / left-parse-string 2drop
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje \ lookup fs in dsl
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje dsl-lookup if ( )
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje true exit ( not-found )
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje then ( ds-obj# )
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje get-rootobj# ( fsroot-obj# )
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje false ( fsroot-obj# found )
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje ;
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje \ lookup file is current directory
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje : dirlook ( file$ dn -- not-found? )
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje \ . and .. are magic
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje -rot 2dup " ." $= if ( dn file$ )
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje 3drop false exit ( found )
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje then
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje 2dup " .." $= if
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje 2drop >znode zp_parent ( obj# )
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje else ( dn file$ )
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje \ search dir
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje current-obj# to search-obj#
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje zap-lookup if ( )
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje true exit ( not-found )
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje then ( obj# )
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje then ( obj# )
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje get-fs-dnode false ( found )
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje ;
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje /buf-len instance buffer: fpath-buf
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje : clr-fpath-buf ( -- ) fpath-buf /buf-len erase ;
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje : fpath-buf$ ( -- path$ ) fpath-buf cscount ;
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje \ copy symlink target to adr
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje : readlink ( dst dn -- )
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje dup fsize tuck /zn-slink > if ( dst size dn )
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje \ contents in 1st block
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje temp-space over dn-bsize ( dst size dn t-adr bsize )
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje rot 0 lblk#>bp read-bp ( dst size )
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje temp-space ( dst size src )
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje else ( dst size dn )
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje \ contents in dnode
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje >znode /znode + ( dst size src )
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje then ( dst size src )
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje -rot move ( )
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje ;
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje \ modify tail to account for symlink
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje : follow-symlink ( tail$ -- tail$' )
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje clr-fpath-buf ( tail$ )
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje fpath-buf dnode readlink
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje \ append to current path
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje ?dup if ( tail$ )
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje " /" fpath-buf$ $append ( tail$ )
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje fpath-buf$ $append ( )
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje else drop then ( )
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje fpath-buf$ ( path$ )
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje \ get directory that starts changed path
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje over c@ ascii / = if ( path$ )
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje str++ root-obj# ( path$' obj# )
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje else ( path$ )
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje search-obj# ( path$ obj# )
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje then ( path$ obj# )
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje get-fs-dnode ( path$ )
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje ;
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje \ open dnode at path
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje : lookup ( path$ -- not-found? )
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje \ get directory that starts path
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje over c@ ascii / = if
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje str++ root-obj# ( path$' obj# )
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje else
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje current-obj# ( path$ obj# )
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje then ( path$ obj# )
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje get-fs-dnode ( path$ )
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje \ lookup each path component
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje begin ( path$ )
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje ascii / left-parse-string ( path$ file$ )
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje dup while
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje dnode dir? 0= if
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje 2drop true exit ( not-found )
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje then ( path$ file$ )
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje dnode dirlook if ( path$ )
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje 2drop true exit ( not-found )
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje then ( path$ )
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje dnode symlink? if
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje follow-symlink ( path$' )
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje then ( path$ )
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje repeat ( path$ file$ )
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje 2drop 2drop false ( found )
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje ;
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje
e7cbe64f7a72dae5cb44f100db60ca88f3313c65gw \
e7cbe64f7a72dae5cb44f100db60ca88f3313c65gw \ ZFS volume (ZVOL) routines
e7cbe64f7a72dae5cb44f100db60ca88f3313c65gw \
e7cbe64f7a72dae5cb44f100db60ca88f3313c65gw 1 constant zvol-data#
e7cbe64f7a72dae5cb44f100db60ca88f3313c65gw 2 constant zvol-prop#
e7cbe64f7a72dae5cb44f100db60ca88f3313c65gw
e7cbe64f7a72dae5cb44f100db60ca88f3313c65gw 0 instance value zv-dn
e7cbe64f7a72dae5cb44f100db60ca88f3313c65gw
e7cbe64f7a72dae5cb44f100db60ca88f3313c65gw : get-zvol ( zvol$ -- not-found? )
e7cbe64f7a72dae5cb44f100db60ca88f3313c65gw dsl-lookup if
e7cbe64f7a72dae5cb44f100db60ca88f3313c65gw drop true exit ( failed )
e7cbe64f7a72dae5cb44f100db60ca88f3313c65gw then ( ds-obj# )
e7cbe64f7a72dae5cb44f100db60ca88f3313c65gw
e7cbe64f7a72dae5cb44f100db60ca88f3313c65gw \ get zvol objset
e7cbe64f7a72dae5cb44f100db60ca88f3313c65gw get-mos-dnode ( )
e7cbe64f7a72dae5cb44f100db60ca88f3313c65gw zv-dn dnode get-objset
e7cbe64f7a72dae5cb44f100db60ca88f3313c65gw false ( succeeded )
e7cbe64f7a72dae5cb44f100db60ca88f3313c65gw ;
e7cbe64f7a72dae5cb44f100db60ca88f3313c65gw
e7cbe64f7a72dae5cb44f100db60ca88f3313c65gw \ get zvol data dnode
e7cbe64f7a72dae5cb44f100db60ca88f3313c65gw : zvol-data ( -- )
e7cbe64f7a72dae5cb44f100db60ca88f3313c65gw zv-dn zvol-data# get-dnode
e7cbe64f7a72dae5cb44f100db60ca88f3313c65gw ;
e7cbe64f7a72dae5cb44f100db60ca88f3313c65gw
e7cbe64f7a72dae5cb44f100db60ca88f3313c65gw : zvol-size ( -- size )
e7cbe64f7a72dae5cb44f100db60ca88f3313c65gw zv-dn zvol-prop# get-dnode
e7cbe64f7a72dae5cb44f100db60ca88f3313c65gw dnode " size" zap-lookup if
e7cbe64f7a72dae5cb44f100db60ca88f3313c65gw " no zvol size" die
e7cbe64f7a72dae5cb44f100db60ca88f3313c65gw then ( size )
e7cbe64f7a72dae5cb44f100db60ca88f3313c65gw ;
e7cbe64f7a72dae5cb44f100db60ca88f3313c65gw
e7cbe64f7a72dae5cb44f100db60ca88f3313c65gw
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje \
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje \ ZFS installation routines
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje \
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje \ ZFS file interface
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje struct
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje /x field >busy
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje /x field >offset
e7cbe64f7a72dae5cb44f100db60ca88f3313c65gw /x field >fsize
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje /dnode field >dnode
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje constant /file-record
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje d# 10 constant #opens
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje #opens /file-record * constant /file-records
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje /file-records instance buffer: file-records
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje -1 instance value current-fd
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje : fd>record ( fd -- rec ) /file-record * file-records + ;
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje : file-offset@ ( -- off ) current-fd fd>record >offset x@ ;
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje : file-offset! ( off -- ) current-fd fd>record >offset x! ;
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje : file-dnode ( -- dn ) current-fd fd>record >dnode ;
e7cbe64f7a72dae5cb44f100db60ca88f3313c65gw : file-size ( -- size ) current-fd fd>record >fsize x@ ;
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje : file-bsize ( -- bsize ) file-dnode dn-bsize ;
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje \ find free fd slot
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje : get-slot ( -- fd false | true )
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje #opens 0 do
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje i fd>record >busy x@ 0= if
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje i false unloop exit
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje then
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje loop true
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje ;
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje : free-slot ( fd -- )
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje 0 swap fd>record >busy x!
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje ;
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje \ init fd to offset 0 and copy dnode
e7cbe64f7a72dae5cb44f100db60ca88f3313c65gw : init-fd ( fsize fd -- )
e7cbe64f7a72dae5cb44f100db60ca88f3313c65gw fd>record ( fsize rec )
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje dup >busy 1 swap x!
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje dup >dnode dnode swap /dnode move
e7cbe64f7a72dae5cb44f100db60ca88f3313c65gw dup >fsize rot swap x! ( rec )
e7cbe64f7a72dae5cb44f100db60ca88f3313c65gw >offset 0 swap x! ( )
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje ;
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje \ make fd current
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje : set-fd ( fd -- error? )
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje dup fd>record >busy x@ 0= if ( fd )
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje drop true exit ( failed )
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje then ( fd )
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje to current-fd false ( succeeded )
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje ;
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje \ read next fs block
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje : file-bread ( adr -- )
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje file-bsize ( adr len )
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje file-offset@ over / ( adr len blk# )
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje file-dnode swap lblk#>bp ( adr len bp )
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje read-bp ( )
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje ;
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje \ advance file io stack by n
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje : fio+ ( # adr len n -- #+n adr+n len-n )
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje dup file-offset@ + file-offset!
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje dup >r - -rot ( len' # adr r: n )
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje r@ + -rot ( adr' len' # r: n )
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje r> + -rot ( #' adr' len' )
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje ;
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje
629270abbcc9bcad8f09aeb9500f67a1933334d1jgj
c713350eb0c205161e2a4ab06cd996300721ac78John Johnson /max-bsize 5 *
c713350eb0c205161e2a4ab06cd996300721ac78John Johnson /uber-block +
c713350eb0c205161e2a4ab06cd996300721ac78John Johnson /dnode 6 * +
c713350eb0c205161e2a4ab06cd996300721ac78John Johnson /disk-block 6 * + ( size )
629270abbcc9bcad8f09aeb9500f67a1933334d1jgj \ ugh - sg proms can't free 512k allocations
629270abbcc9bcad8f09aeb9500f67a1933334d1jgj \ that aren't a multiple of 512k in size
c713350eb0c205161e2a4ab06cd996300721ac78John Johnson h# 8.0000 roundup ( size' )
629270abbcc9bcad8f09aeb9500f67a1933334d1jgj constant alloc-size
629270abbcc9bcad8f09aeb9500f67a1933334d1jgj
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje : allocate-buffers ( -- )
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje alloc-size h# a0.0000 vmem-alloc dup 0= if
e7cbe64f7a72dae5cb44f100db60ca88f3313c65gw " no memory" die
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje then ( adr )
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje dup to temp-space /max-bsize + ( adr )
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje dup to dn-cache /max-bsize + ( adr )
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje dup to blk-space /max-bsize + ( adr )
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje dup to ind-cache /max-bsize + ( adr )
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje dup to zap-space /max-bsize + ( adr )
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje dup to uber-block /uber-block + ( adr )
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje dup to mos-dn /dnode + ( adr )
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje dup to obj-dir /dnode + ( adr )
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje dup to root-dsl /dnode + ( adr )
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje dup to fs-dn /dnode + ( adr )
e7cbe64f7a72dae5cb44f100db60ca88f3313c65gw dup to zv-dn /dnode + ( adr )
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje dup to dnode /dnode + ( adr )
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje to gang-space ( )
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje \ zero instance buffers
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje file-records /file-records erase
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje bootprop-buf /buf-len erase
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje ;
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje : release-buffers ( -- )
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje temp-space alloc-size mem-free
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje ;
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje external
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje : open ( -- okay? )
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje my-args dev-open dup 0= if
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje exit ( failed )
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje then to dev-ih
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje allocate-buffers
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje scan-vdev
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje get-ub
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje get-root-dsl
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje true
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje ;
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje : open-fs ( fs$ -- okay? )
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje fs>rootobj# if ( )
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje false ( failed )
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje else ( obj# )
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje to root-obj# true ( succeeded )
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje then ( okay? )
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje ;
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje : close ( -- )
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje dev-ih dev-close
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje 0 to dev-ih
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje release-buffers
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje ;
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje : open-file ( path$ -- fd true | false )
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje \ open default fs if no open-fs
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje root-obj# 0= if
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje prop>rootobj# to root-obj#
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje then
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje get-slot if
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje 2drop false exit ( failed )
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje then -rot ( fd path$ )
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje lookup if ( fd )
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje drop false exit ( failed )
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje then ( fd )
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje
e7cbe64f7a72dae5cb44f100db60ca88f3313c65gw dnode fsize over init-fd
e7cbe64f7a72dae5cb44f100db60ca88f3313c65gw true ( fd succeeded )
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje ;
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje
e7cbe64f7a72dae5cb44f100db60ca88f3313c65gw : open-volume ( vol$ -- okay? )
e7cbe64f7a72dae5cb44f100db60ca88f3313c65gw get-slot if
e7cbe64f7a72dae5cb44f100db60ca88f3313c65gw 2drop false exit ( failed )
e7cbe64f7a72dae5cb44f100db60ca88f3313c65gw then -rot ( fd vol$ )
e7cbe64f7a72dae5cb44f100db60ca88f3313c65gw
e7cbe64f7a72dae5cb44f100db60ca88f3313c65gw get-zvol if ( fd )
e7cbe64f7a72dae5cb44f100db60ca88f3313c65gw drop false exit ( failed )
e7cbe64f7a72dae5cb44f100db60ca88f3313c65gw then
e7cbe64f7a72dae5cb44f100db60ca88f3313c65gw
e7cbe64f7a72dae5cb44f100db60ca88f3313c65gw zvol-size over ( fd size fd )
e7cbe64f7a72dae5cb44f100db60ca88f3313c65gw zvol-data init-fd ( fd )
e7cbe64f7a72dae5cb44f100db60ca88f3313c65gw true ( fd succeeded )
e7cbe64f7a72dae5cb44f100db60ca88f3313c65gw ;
e7cbe64f7a72dae5cb44f100db60ca88f3313c65gw
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje : close-file ( fd -- )
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje free-slot ( )
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje ;
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje : size-file ( fd -- size )
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje set-fd if 0 else file-size then
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje ;
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje : seek-file ( off fd -- off true | false )
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje set-fd if ( off )
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje drop false exit ( failed )
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje then ( off )
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje
e7cbe64f7a72dae5cb44f100db60ca88f3313c65gw dup file-size x> if ( off )
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje drop false exit ( failed )
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje then ( off )
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje dup file-offset! true ( off succeeded )
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje ;
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje : read-file ( adr len fd -- #read )
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje set-fd if ( adr len )
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje 2drop 0 exit ( 0 )
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje then ( adr len )
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje \ adjust len if reading past eof
e7cbe64f7a72dae5cb44f100db60ca88f3313c65gw dup file-offset@ + file-size x> if
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje dup file-offset@ + file-size - -
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje then
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje dup 0= if nip exit then
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje 0 -rot ( #read adr len )
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje \ initial partial block
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje file-offset@ file-bsize mod ?dup if ( #read adr len off )
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje temp-space file-bread
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje 2dup file-bsize swap - min ( #read adr len off cpy-len )
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje 2over drop -rot ( #read adr len adr off cpy-len )
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje >r temp-space + swap ( #read adr len cpy-src adr r: cpy-len )
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje r@ move r> fio+ ( #read' adr' len' )
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje then ( #read adr len )
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje dup file-bsize / 0 ?do ( #read adr len )
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje over file-bread
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje file-bsize fio+ ( #read' adr' len' )
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje loop ( #read adr len )
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje \ final partial block
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje dup if ( #read adr len )
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje temp-space file-bread
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje 2dup temp-space -rot move ( #read adr len )
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje dup fio+ ( #read' adr' 0 )
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje then 2drop ( #read )
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje ;
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje : cinfo-file ( fd -- bsize fsize comp? )
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje set-fd if
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje 0 0 0
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje else
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje file-bsize file-size ( bsize fsize )
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje \ zfs does internal compression
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje 0 ( bsize fsize comp? )
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje then
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje ;
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje \ read ramdisk fcode at rd-offset
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje : get-rd ( adr len -- )
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje rd-offset dev-ih read-disk
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje ;
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje : bootprop
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje " /" bootprop$ $append
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje bootfs-obj# (xu.) bootprop$ $append
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje bootprop$ encode-string " zfs-bootfs" ( propval propname )
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje true
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje ;
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje : chdir ( dir$ -- )
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje current-obj# -rot ( obj# dir$ )
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje lookup if ( obj# )
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje to current-obj# ( )
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje ." no such dir" cr exit
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje then ( obj# )
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje dnode dir? 0= if ( obj# )
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje to current-obj# ( )
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje ." not a dir" cr exit
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje then drop ( )
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje ;
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje : dir ( -- )
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje current-obj# get-fs-dnode
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje dnode zap-print
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje ;
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setje
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setjefinish-device
986fd29a0dc13f7608ef7f508f6e700bd7bc2720setjepop-package