| # apebs0 = # wlar, LEB_SIZE = (n2 + m0) + m1, vols0[v][m] = unmapped, apebs = apebs0, n0 = m1, n1 = m2, q = q0, vols = vols0, vtblpnum0 = vtblpnum, vtblpnum1 = m0, vtblpnum2 = m, m < # vols0[v], bflipset-cons(bflipset, wlar), is-aligned(m1, EB_PAGE_SIZE), is-aligned(m0, EB_PAGE_SIZE), ubi-io-inv(apebs0), unique-sqns(apebs0), valid-ebatbl(apebs0, wlar, vols0, vtblpnum), valid-eraseq(apebs0, q0), valid-eraseq(wlar, q0), valid-eraseq(q0), valid-global-sqn(apebs0, sqnum), valid-vtbl(apebs0, vols0, wlar, vtblpnum), valid-wl(apebs0, wlar), v ∈ vols0, m1 ≤ LEB_SIZE, m1 + m2 ≤ # buf, m0 + m1 ≤ LEB_SIZE ⊦ ⟪let vtblpnum = 0 in {err := EIO; while err ≠ ESUCCESS ∧ vtblpnum ≤ UBI_WRITE_RETRIES do {/* (prepost-write-multiple : invariant ubi-cons(apebs, vols, wlar, q, bflipset, vtblpnum0, sqnum) ∧ ubi-io-inv(apebs) ∧ v ∈ vols ∧ vtblpnum2 < # vols[v] ∧ (vols`)[v][vtblpnum2] = unmapped ∧ id(apebs, apebs`, mapped-pebs(vols`)) ∧ q.lebrefs ⊆ q`.lebrefs ++ (v × vtblpnum2) ∧ n1 + n0 ≤ # buf ∧ (n0 = 0 → q.lebrefs ⊆ q`.lebrefs) ∧ (err = ESUCCESS ∨ ⌊err⌋ ) ∧ (err ≠ ESUCCESS → vols = vols`) ∧ ( err = ESUCCESS → (∃ n. vols = (vols`)[v, (vols`)[v][vtblpnum2, ⌜n⌝ ]] ∧ (n0 ≠ 0 → apebs[n].fill = vtblpnum1 + n0) ∧ (n0 = 0 → apebs[n].fill = 0) ∧ apebs[n].data = mkempbuf(vtblpnum1) + subarray(buf, n1, n0) + mkempbuf(LEB_SIZE - n0 - vtblpnum1))) ∧ is-aligned(vtblpnum1, EB_PAGE_SIZE) ∧ is-aligned(n0, EB_PAGE_SIZE) ∧ vtblpnum1 + n0 ≤ LEB_SIZE wfbound UBI_WRITE_RETRIES + 1 - vtblpnum) */; ubi_write_once#(v, vtblpnum2, vtblpnum1, n1, n0, buf; vols, wlar, q, sqnum, apebs; err); vtblpnum := vtblpnum +1}}⟫ ( # apebs = # wlar ∧ unique-sqns(apebs) ∧ valid-global-sqn(apebs, sqnum) ∧ valid-wl(apebs, wlar) ∧ valid-eraseq(q) ∧ valid-eraseq(wlar, q) ∧ valid-eraseq(apebs, q) ∧ ¬ VTBL_VOLID ∈ vols ∧ bflipset-cons(bflipset, wlar) ∧ valid-ebatbl(apebs, wlar, vols, vtblpnum) ∧ valid-vtbl(apebs, vols, wlar, vtblpnum) ∧ ubi-io-inv(apebs) ∧ id(apebs, apebs0, mapped-pebs(vols0)) ∧ q.lebrefs ⊆ q0.lebrefs ++ (v × m) ∧ (m1 = 0 → q.lebrefs ⊆ q0.lebrefs) ∧ (err = ESUCCESS ∨ ⌊err⌋ ) ∧ (err ≠ ESUCCESS → vols = vols0) ∧ ( err = ESUCCESS → (∃ n. vols = vols0[v, vols0[v][m, ⌜n⌝ ]] ∧ (m1 ≠ 0 → apebs[n].fill = m0 + m1) ∧ (m1 = 0 → apebs[n].fill = 0) ∧ apebs[n].data = mkempbuf(m0) + subarray(buf, m2, m1) + mkempbuf(n2)))), VTBL_VOLID ∈ vols0, vtblpnum ∈ q0 |
# apebs0 = # wlar, LEB_SIZE = (n2 + m0) + m1, vols0[v][m] = unmapped, apebs = apebs0, n0 = m1, n1 = m2, q = q0, vols = vols0, vtblpnum = 0, vtblpnum0 = vtblpnum3, vtblpnum1 = m0, vtblpnum2 = m, m < # vols0[v], bflipset-cons(bflipset, wlar), is-aligned(m0, EB_PAGE_SIZE), is-aligned(m1, EB_PAGE_SIZE), ubi-io-inv(apebs0), unique-sqns(apebs0), valid-ebatbl(apebs0, wlar, vols0, vtblpnum3), valid-eraseq(q0), valid-eraseq(wlar, q0), valid-eraseq(apebs0, q0), valid-global-sqn(apebs0, sqnum), valid-vtbl(apebs0, vols0, wlar, vtblpnum3), valid-wl(apebs0, wlar), v ∈ vols0, m0 + m1 ≤ LEB_SIZE, m1 + m2 ≤ # buf, m1 ≤ LEB_SIZE ⊦ ⟪err := EIO; while err ≠ ESUCCESS ∧ vtblpnum ≤ UBI_WRITE_RETRIES do {/* (prepost-write-multiple : invariant ubi-cons(apebs, vols, wlar, q, bflipset, vtblpnum0, sqnum) ∧ ubi-io-inv(apebs) ∧ v ∈ vols ∧ vtblpnum2 < # vols[v] ∧ (vols`)[v][vtblpnum2] = unmapped ∧ id(apebs, apebs`, mapped-pebs(vols`)) ∧ q.lebrefs ⊆ q`.lebrefs ++ (v × vtblpnum2) ∧ n1 + n0 ≤ # buf ∧ (n0 = 0 → q.lebrefs ⊆ q`.lebrefs) ∧ (err = ESUCCESS ∨ ⌊err⌋ ) ∧ (err ≠ ESUCCESS → vols = vols`) ∧ ( err = ESUCCESS → (∃ n. vols = (vols`)[v, (vols`)[v][vtblpnum2, ⌜n⌝ ]] ∧ (n0 ≠ 0 → apebs[n].fill = vtblpnum1 + n0) ∧ (n0 = 0 → apebs[n].fill = 0) ∧ apebs[n].data = mkempbuf(vtblpnum1) + subarray(buf, n1, n0) + mkempbuf(LEB_SIZE - n0 - vtblpnum1))) ∧ is-aligned(vtblpnum1, EB_PAGE_SIZE) ∧ is-aligned(n0, EB_PAGE_SIZE) ∧ vtblpnum1 + n0 ≤ LEB_SIZE wfbound UBI_WRITE_RETRIES + 1 - vtblpnum) */; ubi_write_once#(v, vtblpnum2, vtblpnum1, n1, n0, buf; vols, wlar, q, sqnum, apebs; err); vtblpnum := vtblpnum +1}⟫ ( # apebs = # wlar ∧ unique-sqns(apebs) ∧ valid-global-sqn(apebs, sqnum) ∧ valid-wl(apebs, wlar) ∧ valid-eraseq(q) ∧ valid-eraseq(wlar, q) ∧ valid-eraseq(apebs, q) ∧ ¬ VTBL_VOLID ∈ vols ∧ bflipset-cons(bflipset, wlar) ∧ valid-ebatbl(apebs, wlar, vols, vtblpnum3) ∧ valid-vtbl(apebs, vols, wlar, vtblpnum3) ∧ ubi-io-inv(apebs) ∧ id(apebs, apebs0, mapped-pebs(vols0)) ∧ q.lebrefs ⊆ q0.lebrefs ++ (v × m) ∧ (m1 = 0 → q.lebrefs ⊆ q0.lebrefs) ∧ (err = ESUCCESS ∨ ⌊err⌋ ) ∧ (err ≠ ESUCCESS → vols = vols0) ∧ ( err = ESUCCESS → (∃ n. vols = vols0[v, vols0[v][m, ⌜n⌝ ]] ∧ (m1 ≠ 0 → apebs[n].fill = m0 + m1) ∧ (m1 = 0 → apebs[n].fill = 0) ∧ apebs[n].data = mkempbuf(m0) + subarray(buf, m2, m1) + mkempbuf(n2)))), vtblpnum3 ∈ q0, VTBL_VOLID ∈ vols0