| dirs[ino] = mkdir(m, md, # links(ino, dirs), m1, entries), dirs[p_ino] = mkdir(m0, md0, m2, m3, entries0), p = str ' + p2, p_ino = ino, afs-cons(dirs, files), ispath(q, ROOT_INO, ino, dirs, files), px(user, md), ino ∈ dirs, ⌊err0⌋ , q ≠ ε → px(user, parent(q), ROOT_INO, dirs, files), links(ino, dirs) ≠ ∅ ∨ ino = ROOT_INO, ∀ p1, err, p, p_ino, ino, dirs, files, q, user, asynced. # p1 < #(str + p2) → err = ESUCCESS ∧ p = p1 ∧ p_ino = ino ∧ afs-cons(dirs, files) ∧ ispath(q, ROOT_INO, ino, dirs, files) ∧ ino ∈ dirs ∧ (q ≠ ε → px(user, parent(q), ROOT_INO, dirs, files)) → [while p ≠ ε ∧ err = ESUCCESS do {choose inode with true in vfs_may_lookup#(ino, user, dirs, files, asynced; inode, err); if err = ESUCCESS then let dent = negdentry(p.head) in {afs_lookup#(ino, dirs, files, asynced; dent, err); if err = ESUCCESS then {ino := dent.ino; p := p.tail}}}] ( ⌊err⌋ ∨ err = ESUCCESS ∧ ispath(p1, p_ino, ino, dirs, files) ∧ px-parent(user, q + p1, ROOT_INO, dirs, files) ∨ err = ENOENT ∧ ¬ ispath(p1, p_ino, dirs, files) ∨ err = EACCESS ∧ p1 ≠ ε ∧ (∃ p'. p' ⊑ parent(p1) ∧ ispath(p', p_ino, dirs, files) ∧ ¬ px(user, q + p', ROOT_INO, dirs, files))) ⊦ [while p ≠ ε ∧ err0 = ESUCCESS do {choose inode with true in vfs_may_lookup#(ino, user, dirs, files, asynced; inode, err0); if err0 = ESUCCESS then let dent = negdentry(p.head) in {afs_lookup#(ino, dirs, files, asynced; dent, err0); if err0 = ESUCCESS then {ino := dent.ino; p := p.tail}}}] ( ⌊err0⌋ ∨ err0 = ESUCCESS ∧ p_ino ∈ dirs ∧ str ∈ entries0 ∧ ispath(p2, entries0[str], ino, dirs, files) ∧ px-parent(user, q + str ' + p2, ROOT_INO, dirs, files) ∨ err0 = ENOENT ∧ (¬ p_ino ∈ dirs ∨ ¬ str ∈ entries0 ∨ ¬ ispath(p2, entries0[str], dirs, files)) ∨ err0 = EACCESS ∧ (∃ p'. p' ⊑ parent(str ' + p2) ∧ ispath(p', p_ino, dirs, files) ∧ ¬ px(user, q + p', ROOT_INO, dirs, files))) |
dirs[ino] = mkdir(m0, md0, # links(ino, dirs), m3, entries0), p = str ' + p2, p_ino = ino, afs-cons(dirs, files), ispath(q, ROOT_INO, ino, dirs, files), px(user, md0), ino ∈ dirs, ⌊err0⌋ , q ≠ ε → px(user, parent(q), ROOT_INO, dirs, files), links(ino, dirs) ≠ ∅ ∨ ino = ROOT_INO, ∀ p1, err, p, p_ino, ino, dirs, files, q, user, asynced. # p1 < #(str + p2) → err = ESUCCESS ∧ p = p1 ∧ p_ino = ino ∧ afs-cons(dirs, files) ∧ ispath(q, ROOT_INO, ino, dirs, files) ∧ ino ∈ dirs ∧ (q ≠ ε → px(user, parent(q), ROOT_INO, dirs, files)) → [while p ≠ ε ∧ err = ESUCCESS do {choose inode with true in vfs_may_lookup#(ino, user, dirs, files, asynced; inode, err); if err = ESUCCESS then let dent = negdentry(p.head) in {afs_lookup#(ino, dirs, files, asynced; dent, err); if err = ESUCCESS then {ino := dent.ino; p := p.tail}}}] ( ⌊err⌋ ∨ err = ESUCCESS ∧ ispath(p1, p_ino, ino, dirs, files) ∧ px-parent(user, q + p1, ROOT_INO, dirs, files) ∨ err = ENOENT ∧ ¬ ispath(p1, p_ino, dirs, files) ∨ err = EACCESS ∧ p1 ≠ ε ∧ (∃ p'. p' ⊑ parent(p1) ∧ ispath(p', p_ino, dirs, files) ∧ ¬ px(user, q + p', ROOT_INO, dirs, files))) ⊦ [while p ≠ ε ∧ err0 = ESUCCESS do {choose inode with true in vfs_may_lookup#(ino, user, dirs, files, asynced; inode, err0); if err0 = ESUCCESS then let dent = negdentry(p.head) in {afs_lookup#(ino, dirs, files, asynced; dent, err0); if err0 = ESUCCESS then {ino := dent.ino; p := p.tail}}}] ( ⌊err0⌋ ∨ err0 = ESUCCESS ∧ p_ino ∈ dirs ∧ str ∈ entries0 ∧ ispath(p2, entries0[str], ino, dirs, files) ∧ px-parent(user, q + str ' + p2, ROOT_INO, dirs, files) ∨ err0 = ENOENT ∧ (¬ p_ino ∈ dirs ∨ ¬ str ∈ entries0 ∨ ¬ ispath(p2, entries0[str], dirs, files)) ∨ err0 = EACCESS ∧ (∃ p'. p' ⊑ parent(str ' + p2) ∧ ispath(p', p_ino, dirs, files) ∧ ¬ px(user, q + p', ROOT_INO, dirs, files)))
Used simplifier rules: ⊦ mkdir(m, md, m0, m1, entries) = mkdir(m2, md0, m3, m4, entries0) ↔ m = m2 ∧ md = md0 ∧ m0 = m3 ∧ m1 = m4 ∧ entries = entries0; (ws)%afs-cons-dir-nlink: ⊦ afs-cons(dirs, files) ∧ ino ∈ dirs ∧ dirs[ino] = mkdir(n0, md, n, n1, entries) → # links(ino, dirs) = n; (forward) from specification afs-base