| ubi_scan_all#(LEBSIZE, APEBS; RECS, WLARRAY, ERASEQ, BFLIPSET, SQNUM; VALIDCOUNT, VALIDECSUM, INVALIDECS, ERR) {RECS := ∅; BFLIPSET := ∅; VALIDCOUNT := 0; VALIDECSUM := 0; INVALIDECS := []; let N = ?, PNUM = 0 in {ERASEQ := []; SQNUM := 0; ERR := ESUCCESS; aubi_io_get_blockcount#(APEBS; ; N); WLARRAY := mkwlarray(N); WLARRAY := fill(WLARRAY, wl-entry(0, free)); while PNUM < N ∧ ERR = ESUCCESS do {/* (prepost-scan-all: invariant scan-all-inv(PNUM, APEBS, RECS, WLARRAY, ERASEQ, BFLIPSET, INVALIDECS, SQNUM, ERR) wfbound # APEBS - PNUM) */; let ISBAD = ? in {aubi_io_isbad#(PNUM, APEBS; ; ISBAD, ERR); if ERR = ESUCCESS then if ISBAD then WLARRAY[PNUM].status := erroneous else let AEHDR = ?, BITFLIPS = ? in {aubi_io_read_echdr#(PNUM, APEBS; AEHDR; BITFLIPS, ERR); if ERR = ESUCCESS then if ¬ AEHDR.valid? then {INVALIDECS := PNUM + INVALIDECS; WLARRAY[PNUM].status := erasing; ERASEQ := ERASEQ + eq-entry(PNUM, none)} else let AVHDR = ? in {VALIDCOUNT := VALIDCOUNT + 1; VALIDECSUM := VALIDECSUM + AEHDR.ec; WLARRAY[PNUM].ec := AEHDR.ec; aubi_io_read_vidhdr#(PNUM, APEBS; AVHDR; BITFLIPS, ERR); if ERR = ESUCCESS then if AVHDR = empty then if BITFLIPS then {WLARRAY[PNUM].status := erasing; ERASEQ := ERASEQ + eq-entry(PNUM, none)} else WLARRAY[PNUM].status := free else if AVHDR.valid? then let BUF = mkbuf(LEBSIZE) in {if AVHDR.size ≠ 0 then let BITFLIPS0 = ? in {aubi_io_read_data#(PNUM, 0, 0, LEBSIZE, APEBS; BUF; BITFLIPS0, ERR); BITFLIPS := BITFLIPS ∨ BITFLIPS0}; if ERR = ESUCCESS then let LADR = AVHDR.vol × AVHDR.leb, N = 0 in {if LADR ∈ RECS then N := RECS[LADR].sqn; if AVHDR.size ≠ 0 → AVHDR.size ≤ datasize(BUF) ∧ AVHDR.checksum = checksum(BUF, AVHDR.size) then {SQNUM := max(SQNUM, AVHDR.sqn + 1); if AVHDR.sqn ≥ N then {WLARRAY[PNUM].status := used; if BITFLIPS then BFLIPSET := BFLIPSET ++ PNUM; if LADR ∈ RECS then let PNUM0 = RECS[LADR].pnum in {BFLIPSET := BFLIPSET -- PNUM0; WLARRAY[PNUM0].status := erasing; ERASEQ := ERASEQ + eq-entry(PNUM0, AVHDR.vol × AVHDR.leb)}; RECS[LADR] := recovery-entry(PNUM, AVHDR.sqn)} else {WLARRAY[PNUM].status := erasing; ERASEQ := ERASEQ + eq-entry(PNUM, LADR.vol × LADR.leb)}} else {WLARRAY[PNUM].status := erasing; ERASEQ := ERASEQ + eq-entry(PNUM, none)}}} else {WLARRAY[PNUM].status := erasing; ERASEQ := ERASEQ + eq-entry(PNUM, none)}}}; PNUM := PNUM + 1}}} } |