| ubi_write_multiple#(VOLID, LNUM, OFFSET, N0, N, BUF, BFLIPSET, VTBLPNUM; VOLS, WLARRAY, ERASEQ, SQNUM, APEBS; ERR) {ERR := EIO; let TRIES = 0 in while ERR ≠ ESUCCESS ∧ TRIES ≤ UBI_WRITE_RETRIES do {/* (prepost-write-multiple : invariant ubi-cons(APEBS, VOLS, WLARRAY, ERASEQ, BFLIPSET, VTBLPNUM, SQNUM) ∧ ubi-io-inv(APEBS) ∧ VOLID ∈ VOLS ∧ LNUM < # VOLS[VOLID] ∧ (VOLS`)[VOLID][LNUM] = unmapped ∧ id(APEBS, APEBS`, mapped-pebs(VOLS`)) ∧ ERASEQ.lebrefs ⊆ ERASEQ`.lebrefs ++ (VOLID × LNUM) ∧ N0 + N ≤ # BUF ∧ (N = 0 → ERASEQ.lebrefs ⊆ ERASEQ`.lebrefs) ∧ (ERR = ESUCCESS ∨ ⌊ERR⌋ ) ∧ (ERR ≠ ESUCCESS → VOLS = VOLS`) ∧ ( ERR = ESUCCESS → (∃ n. VOLS = (VOLS`)[VOLID, (VOLS`)[VOLID][LNUM, ⌜n⌝ ]] ∧ (N ≠ 0 → APEBS[n].fill = OFFSET + N) ∧ (N = 0 → APEBS[n].fill = 0) ∧ APEBS[n].data = mkempbuf(OFFSET) + subarray(BUF, N0, N) + mkempbuf(LEB_SIZE - N - OFFSET))) ∧ is-aligned(OFFSET, EB_PAGE_SIZE) ∧ is-aligned(N, EB_PAGE_SIZE) ∧ OFFSET + N ≤ LEB_SIZE wfbound UBI_WRITE_RETRIES + 1 - TRIES) */; ubi_write_once#(VOLID, LNUM, OFFSET, N0, N, BUF; VOLS, WLARRAY, ERASEQ, SQNUM, APEBS; ERR); TRIES := TRIES +1} } |