| afs_dirs = cache_dirs, afs_files = (cache_files ⊕ cache_pcache) ⊕ cache_icache, err = err0, afs-cons(cache_dirs, (cache_files ⊕ cache_pcache) ⊕ cache_icache), afs-cons(cache_dirs, cache_files), dcache-cons(cache_dcache, cache_dirs, cache_files), icache-cons(cache_icache, cache_dirs, cache_files), pcache-cons(cache_pcache, cache_dirs, cache_files), synced(cache_dirs, cache_icache, cache_pcache), cache_sync → synced(cache_files, cache_icache, cache_pcache), m ∈ cache_dirs ∧ m0 = cache_dirs[m].nlink ∧ m2 = cache_dirs[m].size ∧ m1 = cache_dirs[m].nsubdirs ∧ boolvar ∨ m ∈ cache_files ∧ m0 = ((cache_files ⊕ cache_pcache) ⊕ cache_icache)[m].nlink ∧ m1 = 0 ∧ ¬ boolvar ⊦ ⟪cache_write_inode#(mkinode(m, md, boolvar, m0, m1, m2), cache_sync; err, cache_dirs, cache_files, cache_icache, cache_asynced)⟫ ⟨afs_write_inode#(mkinode(m, md, boolvar, m0, m1, m2); err0, afs_dirs, afs_files; afs_asynced)⟩ (afs_dirs = cache_dirs ∧ afs_files = (cache_files ⊕ cache_pcache) ⊕ cache_icache ∧ (afs_asynced ↔ cache_asynced) ∧ err = err0) |
asynced2 ↔ cache_sync, asynced1 ↔ cache_asynced, afs_dirs = cache_dirs, afs_files = (cache_files ⊕ cache_pcache) ⊕ cache_icache, dirs = cache_dirs, err = err0, files = cache_files, icache = cache_icache, inode0 = mkinode(m, md, boolvar, m0, m1, m2), afs-cons(cache_dirs, cache_files), afs-cons(cache_dirs, (cache_files ⊕ cache_pcache) ⊕ cache_icache), dcache-cons(cache_dcache, cache_dirs, cache_files), icache-cons(cache_icache, cache_dirs, cache_files), pcache-cons(cache_pcache, cache_dirs, cache_files), synced(cache_dirs, cache_icache, cache_pcache), cache_sync → synced(cache_files, cache_icache, cache_pcache), m ∈ cache_dirs ∧ m0 = cache_dirs[m].nlink ∧ m2 = cache_dirs[m].size ∧ m1 = cache_dirs[m].nsubdirs ∧ boolvar ∨ m ∈ cache_files ∧ m0 = ((cache_files ⊕ cache_pcache) ⊕ cache_icache)[m].nlink ∧ m1 = 0 ∧ ¬ boolvar ⊦ ⟪if pre-write-inode(inode0, dirs, files) then let asynced0 = true, inode = ?, asynced = false in {if asynced2 ∨ inode0.directory then {afs_write_inode#(inode0; err, dirs, files; asynced1); asynced0 := false} else err := ESUCCESS; if err = ESUCCESS then icache_get#(inode0.ino, icache; asynced, inode, err); if err = ESUCCESS ∧ asynced then {inode.meta := inode0.meta; if ¬ inode0.directory then inode.size := inode0.size; icache_set#(inode, asynced0; err, icache)} else if asynced0 then err := EFAIL} else abort⟫ ⟨afs_write_inode#(mkinode(m, md, boolvar, m0, m1, m2); err0, afs_dirs, afs_files; afs_asynced)⟩ (afs_dirs = dirs ∧ afs_files = (files ⊕ cache_pcache) ⊕ icache ∧ (afs_asynced ↔ asynced1) ∧ err = err0)
Used simplifier rules: cache_write_inode#(INODE, SYNC; ERR, DIRS, FILES, ICACHE, ASYNCED) {if pre-write-inode(INODE, DIRS, FILES) then let DIRTY = true, INODE0 = ?, HIT = false in {if SYNC ∨ INODE.directory then {afs_write_inode#(INODE; ERR, DIRS, FILES; ASYNCED); DIRTY := false} else ERR := ESUCCESS; if ERR = ESUCCESS then icache_get#(INODE.ino, ICACHE; HIT, INODE0, ERR); if ERR = ESUCCESS ∧ HIT then {INODE0.meta := INODE.meta; if ¬ INODE.directory then INODE0.size := INODE.size; icache_set#(INODE0, DIRTY; ERR, ICACHE)} else if DIRTY then ERR := EFAIL} else abort };