Timings for setattr.v
- /home/gitlab-runner/builds/v6HyzL39/0/coq/coq/_bench/opam.OLD/ocaml-OLD/.opam-switch/build/coq-perennial.dev/./src/program_proof/simple/setattr.v.timing
- /home/gitlab-runner/builds/v6HyzL39/0/coq/coq/_bench/opam.NEW/ocaml-NEW/.opam-switch/build/coq-perennial.dev/./src/program_proof/simple/setattr.v.timing
From RecordUpdate Require Import RecordSet.
Import RecordSetNotations.
From Perennial.algebra Require Import liftable auth_map.
From Perennial.Helpers Require Import Transitions.
From Perennial.program_proof Require Import disk_prelude.
From Goose.github_com.mit_pdos.go_nfsd Require Import simple.
From Perennial.program_proof Require Import obj.obj_proof marshal_proof addr_proof crash_lockmap_proof addr.addr_proof buf.buf_proof.
From Perennial.program_proof Require Import jrnl.sep_jrnl_proof.
From Perennial.program_proof Require Import disk_prelude.
From Perennial.program_proof Require Import disk_lib.
From Perennial.Helpers Require Import NamedProps Map List range_set.
From Perennial.program_logic Require Import spec_assert.
From Perennial.goose_lang.lib Require Import slice.typed_slice into_val.
From Perennial.program_proof Require Import simple.spec simple.invariant simple.common simple.iread simple.iwrite.
Implicit Types (stk:stuckness) (E: coPset).
Variable P : SimpleNFS.State -> iProp Σ.
Context `{Ptimeless : !forall σ, Timeless (P σ)}.
Opaque nfstypes.SETATTR3res.
Lemma is_inode_data_shrink: forall state blk (u: u64) M,
¬ (int.Z (length state) < int.Z u)%Z ->
is_inode_data (length state) blk state M -∗
is_inode_data (Σ:=Σ) (length (take (int.nat u) state)) blk (take (int.nat u) state) M.
iIntros (state blk u γtxn) "%H Hinode_data".
rewrite -> firstn_length_le by lia.
Lemma nfstypes_setattr3res_merge reply s ok fail :
( reply ↦[nfstypes.SETATTR3res :: "Status"] s ∗
reply ↦[nfstypes.SETATTR3res :: "Resok"] ok ∗
reply ↦[nfstypes.SETATTR3res :: "Resfail"] fail ) -∗
reply ↦[struct.t nfstypes.SETATTR3res]{1} (s, (ok, (fail, #()))).
iIntros "(Status & Resok & Resfail)".
iApply struct_fields_split.
Theorem wp_NFSPROC3_SETATTR γ (nfs : loc) (fh : u64) (fhslice : Slice.t) (sattr: SimpleNFS.sattr) (Q : SimpleNFS.res unit -> iProp Σ) dinit :
{{{ is_fs P γ nfs dinit ∗
is_fh fhslice fh ∗
( ∀ σ σ' (r : SimpleNFS.res unit) E,
⌜relation.denote (SimpleNFS.wrapper fh (SimpleNFS.setattr fh sattr)) σ σ' r⌝ -∗
( P σ -∗ |8={E}=> P σ' ∗ Q r ) )
}}}
Nfs__NFSPROC3_SETATTR #nfs
(struct.mk_f nfstypes.SETATTR3args [
"Object" ::= struct.mk_f nfstypes.Nfs_fh3 [
"Data" ::= slice_val fhslice
];
"New_attributes" ::= struct.mk_f nfstypes.Sattr3 [
"Size" ::= struct.mk_f nfstypes.Set_size3 [
"Set_it" ::= match sattr.(SimpleNFS.sattr_size) with | None => #false | Some _ => #true end;
"Size" ::= match sattr.(SimpleNFS.sattr_size) with | None => #0 | Some s => #s end
]
]
])%V
{{{ v,
RET v;
( ⌜ getField_f nfstypes.SETATTR3res "Status" v = #(U32 0) ⌝ ∗
Q (SimpleNFS.OK tt) ) ∨
( ∃ stat,
⌜ getField_f nfstypes.SETATTR3res "Status" v = #(U32 stat) ⌝ ∗
⌜ stat ≠ 0 ⌝ ∗
Q SimpleNFS.Err )
}}}.
iIntros (Φ) "(Hfs & #Hfh & Hfupd) HΦ".
wp_apply wp_ref_of_zero; first by auto.
iIntros (reply) "Hreply".
wp_apply util_proof.wp_DPrintf.
wp_apply (wp_Op__Begin with "[$Histxn $Htxnsys]").
iIntros (γtxn buftx) "Hjrnl".
wp_apply (wp_fh2ino with "Hfh").
wp_apply util_proof.wp_DPrintf.
iIntros (valid) "%Hvalid".
wp_apply (wp_storeField_struct with "Hreply"); first by auto.
iInv "Hsrc" as ">Hopen" "Hclose".
iDestruct ("Hfupd" with "[] HP") as "Hfupd".
destruct (src !! fh) eqn:He.
assert (fh ∈ dom src) as Hin.
iMod "Hfupd" as "[HP HQ]".
iMod ("Hclose" with "[Hsrcheap HP]").
wp_apply (wp_LockMap__Acquire with "[$Hislm]"); first by intuition eauto.
wp_bind (NFSPROC3_SETATTR_internal _ _ _ _).
iApply (wpc_wp _ _ _ _ True).
iApply (use_CrashLocked _ with "Hcrashlocked"); first by eauto.
iApply ncfupd_wpc; iSplit.
iMod (is_inode_stable_crash with "Htxncrash Hstable") as "H".
iSplit; try (iIntros "? !>"); done.
iMod (lift_liftable_into_txn with "Hjrnl Hinode_disk") as "[Hinode_disk Hjrnl]";
[ solve_ndisj .. | ].
iCache with "Hinode_state Hjrnl_durable".
iDestruct (is_jrnl_durable_to_old_pred with "Hjrnl_durable") as "[Hold _]".
iMod (is_inode_crash_prev with "Htxncrash [$Hinode_state $Hold]") as "H".
iSplit; try (iIntros "? !>"); done.
wpc_bind (NFSPROC3_SETATTR_wp _ _ _ _).
wp_apply (wp_ReadInode with "[$Hjrnl_mem $Hinode_enc]"); first by intuition eauto.
iIntros (ip) "(Hjrnl_mem & Hinode_enc & Hinode_mem)".
wp_apply (typed_mem.wp_AllocAt); eauto.
destruct sattr_size; wp_if.
wp_apply (wp_NewSlice (V:=u8)).
iIntros (zeros) "Hzeros".
wp_apply (wp_Inode__Write with "[$Hjrnl_mem $Hinum $Hisize $Hidata $Hinode_data $Hinode_enc Hzeros]").
iDestruct (own_slice_to_small with "Hzeros") as "$".
rewrite replicate_length.
iIntros (wcount ok) "[Hjrnl_mem [(Hinode_mem & Hinode_enc & Hinode_data & %Hok) | Hok]]"; intuition subst.
iDestruct (struct_fields_split with "Hreply") as "Hreply".
iInv "Hsrc" as ">Hopen" "Hclose".
iDestruct (map_valid with "Hsrcheap Hinode_state") as "%Hsrc_fh".
iDestruct (big_sepM_lookup with "Hnooverflow") as %Hnooverflow; eauto.
rewrite replicate_length.
rewrite Z.max_r; last by lia.
iDestruct (is_jrnl_mem_durable with "Hjrnl_mem Hjrnl_durable") as "Hjrnl".
wpc_apply (wpc_Op__CommitWait with "[$Hjrnl $Htxncrash Hinode_enc Hinode_data]").
(* XXX is there a clean version of this? *)
generalize (jrnl_maps_to γtxn).
iIntros "[[H _]|[H0 H1]]".
iDestruct (is_inode_crash_next with "[$Hinode_state $H]") as "H".
iSplit; try (iIntros "? !>"); done.
iInv "Hsrc" as ">Hopen" "Hclose".
iDestruct (map_valid with "Hsrcheap Hinode_state") as "%Hsrc_fh2".
iDestruct (big_sepM_lookup with "Hnooverflow") as %Hnooverflow; eauto.
iDestruct ("Hfupd" with "[] HP") as "Hfupd".
eapply relation.bind_runs with (x:=false).
iMod (map_update with "Hsrcheap Hinode_state") as "[Hsrcheap Hinode_state]".
iMod "Hfupd" as "[HP HQ]".
iMod ("Hclose" with "[Hsrcheap HP]").
iDestruct (big_sepM_delete with "Hnooverflow") as "[H0 H1]"; eauto.
iApply (big_sepM_insert_delete with "[$H1]").
rewrite app_length replicate_length.
rewrite replicate_length in H0.
assert (length state < int.Z u)%Z by (revert Heqb; word).
rewrite -> Z.max_r in Heqb0 by word.
rewrite -> Z.max_r by word.
rewrite !app_length !replicate_length take_length_ge.
replace (length state + (int.Z u - length state))%Z with (int.Z u) by lia.
replace (length state + (int.Z u - length state))%Z with (int.Z u) by lia.
replace (length state + (int.nat u - length state)) with (int.nat u) by lia.
replace (U64 (int.nat u)) with (U64 (int.Z u)) by word.
replace (Z.to_nat (length state)) with (length state) by lia.
rewrite (firstn_all2 state); last by lia.
rewrite drop_ge; last by lia.
2: rewrite replicate_length; lia.
replace (Z.to_nat (int.Z u - length state)) with (int.nat u - length state) by lia.
(* Simulate to get Q, write succeeded *)
iInv "Hsrc" as ">Hopen" "Hclose".
iDestruct (map_valid with "Hsrcheap Hinode_state") as "%Hsrc_fh".
iDestruct (big_sepM_lookup with "Hnooverflow") as %Hnooverflow; eauto.
iDestruct ("Hfupd" with "[] HP") as "Hfupd".
instantiate (3 := false).
iMod (map_update with "Hsrcheap Hinode_state") as "[Hsrcheap Hinode_state]".
iMod "Hfupd" as "[HP HQ]".
iMod ("Hclose" with "[Hsrcheap HP]").
iDestruct (big_sepM_delete with "Hnooverflow") as "[H0 H1]"; eauto.
iApply (big_sepM_insert_delete with "[$H1]").
rewrite app_length replicate_length.
rewrite replicate_length in H0.
iDestruct "Hcommit" as "(Hinode_enc & Hinode_data)".
wpc_frame "Hinode_state Hinode_enc Hinode_data".
iMod (is_inode_crash_prev_own with "Htxncrash [$Hinode_state Hinode_enc Hinode_data]") as "H".
iSplit; try (iIntros "? !>"); done.
assert (length state < int.Z u)%Z by (revert Heqb; word).
rewrite -> Z.max_r in Heqb0 by word.
rewrite -> Z.max_r by word.
rewrite !app_length !replicate_length take_length_ge.
replace (length state + (int.Z u - length state))%Z with (int.Z u) by lia.
replace (length state + (int.Z u - length state))%Z with (int.Z u) by lia.
replace (length state + (int.nat u - length state)) with (int.nat u) by lia.
replace (U64 (int.nat u)) with (U64 (int.Z u)) by word.
replace (Z.to_nat (length state)) with (length state) by lia.
rewrite (firstn_all2 state); last by lia.
rewrite drop_ge; last by lia.
2: rewrite replicate_length; lia.
replace (Z.to_nat (int.Z u - length state)) with (int.nat u - length state) by lia.
iDestruct (struct_fields_split with "Hreply") as "Hreply".
iSplitR "Hinode_state Hinode_enc Hinode_data".
assert (length state < int.Z u)%Z by (revert Heqb; word).
rewrite -> Z.max_r in Heqb0 by word.
rewrite -> Z.max_r by word.
rewrite !app_length !replicate_length take_length_ge.
replace (length state + (int.Z u - length state))%Z with (int.Z u) by lia.
replace (length state + (int.Z u - length state))%Z with (int.Z u) by lia.
replace (length state + (int.nat u - length state)) with (int.nat u) by lia.
replace (U64 (int.nat u)) with (U64 (int.Z u)) by word.
replace (Z.to_nat (length state)) with (length state) by lia.
rewrite (firstn_all2 state); last by lia.
rewrite drop_ge; last by lia.
2: rewrite replicate_length; lia.
replace (Z.to_nat (int.Z u - length state)) with (int.nat u - length state) by lia.
wp_apply (wp_LockMap__Release with "Hcrashlocked").
wp_apply (wp_LoadAt with "[Status Resok Resfail]").
iApply nfstypes_setattr3res_merge.
(* Simulate to get Q, write succeeded *)
iInv "Hsrc" as ">Hopen" "Hclose".
iDestruct (map_valid with "Hsrcheap Hinode_state") as "%Hsrc_fh".
iDestruct (big_sepM_lookup with "Hnooverflow") as %Hnooverflow; eauto.
iDestruct ("Hfupd" with "[] HP") as "Hfupd".
iMod "Hfupd" as "[HP HQ]".
iMod ("Hclose" with "[Hsrcheap HP]").
iDestruct "Hcommit" as "[Hcommit _]".
wpc_frame "Hinode_state Hcommit".
iMod (is_inode_crash_prev_own with "Htxncrash [$Hinode_state $Hcommit]") as "H".
iSplit; try (iIntros "? !>"); done.
iDestruct (struct_fields_split with "Hreply") as "Hreply".
iSplitR "Hinode_state Hcommit".
wp_apply (wp_LockMap__Release with "Hcrashlocked").
wp_apply (wp_LoadAt with "[Status Resok Resfail]").
iApply nfstypes_setattr3res_merge.
iDestruct "Hok" as "(Hinode_mem & Hinode_enc & Hinode_data & %Hok)".
iDestruct (struct_fields_split with "Hreply") as "Hreply".
(* Simulate to get Q after write failed *)
iInv "Hsrc" as ">Hopen" "Hclose".
iDestruct ("Hfupd" with "[] HP") as "Hfupd".
destruct (src !! fh) eqn:He.
eapply relation.bind_runs with (x:=true).
iMod "Hfupd" as "[HP HQ]".
iMod ("Hclose" with "[Hsrcheap HP]").
(* Implicit transaction abort *)
iDestruct (is_jrnl_mem_durable with "Hjrnl_mem Hjrnl_durable") as "Hjrnl".
iDestruct (is_jrnl_to_old_pred with "Hjrnl") as "[Hold _]".
iSplitR "Hinode_state Hold".
iIntros "!> Hcrashlocked".
wp_apply (wp_LockMap__Release with "Hcrashlocked").
wp_apply (wp_LoadAt with "[Status Resok Resfail]").
iApply nfstypes_setattr3res_merge.
wp_apply (wp_Inode__WriteInode with "[$Hjrnl_mem Hinum Hisize Hidata $Hinode_enc]").
iIntros "(Hjrnl_mem & Hinode_enc & Hinode_mem)".
iDestruct (is_jrnl_mem_durable with "Hjrnl_mem Hjrnl_durable") as "Hjrnl".
wpc_apply (wpc_Op__CommitWait with "[$Hjrnl $Htxncrash Hinode_enc Hinode_data]").
(* XXX is there a clean version of this? *)
generalize (jrnl_maps_to γtxn).
iIntros "[[H _]|[H0 H1]]".
iDestruct (is_inode_crash_next with "[$Hinode_state $H]") as "H".
iSplit; try (iIntros "? !>"); done.
iInv "Hsrc" as ">Hopen" "Hclose".
iDestruct (map_valid with "Hsrcheap Hinode_state") as "%Hsrc_fh2".
iDestruct (big_sepM_lookup with "Hnooverflow") as %Hnooverflow; eauto.
iDestruct ("Hfupd" with "[] HP") as "Hfupd".
eapply relation.bind_runs with (x:=false).
iMod (map_update with "Hsrcheap Hinode_state") as "[Hsrcheap Hinode_state]".
iMod "Hfupd" as "[HP HQ]".
assert (int.nat u - length state = 0).
iMod ("Hclose" with "[Hsrcheap HP]").
iDestruct (big_sepM_delete with "Hnooverflow") as "[H0 H1]"; eauto.
iApply (big_sepM_insert_delete with "[$H1]").
rewrite -> firstn_length_le by word.
iDestruct (is_inode_crash_next with "[$Hinode_state H0 H1]") as "H".
iSplit; try (iIntros "? !>"); done.
rewrite -> firstn_length_le by word.
iDestruct (is_inode_data_shrink _ _ u with "H1") as "H1".
rewrite -> firstn_length_le by word.
replace (U64 (Z.of_nat (int.nat u))) with u by word.
(* Simulate to get Q, commit succeeded *)
iInv "Hsrc" as ">Hopen" "Hclose".
iDestruct (map_valid with "Hsrcheap Hinode_state") as "%Hsrc_fh".
iDestruct (big_sepM_lookup with "Hnooverflow") as %Hnooverflow; eauto.
iDestruct ("Hfupd" with "[] HP") as "Hfupd".
instantiate (3 := false).
iMod (map_update with "Hsrcheap Hinode_state") as "[Hsrcheap Hinode_state]".
iMod "Hfupd" as "[HP HQ]".
assert (int.nat u - length state = 0).
iMod ("Hclose" with "[Hsrcheap HP]").
iDestruct (big_sepM_delete with "Hnooverflow") as "[H0 H1]"; eauto.
iApply (big_sepM_insert_delete with "[$H1]").
rewrite firstn_length_le.
iDestruct "Hcommit" as "[Hinode_enc Hinode_data]".
iDestruct (is_inode_data_shrink _ _ u with "Hinode_data") as "Hinode_data"; first by word.
wpc_frame "Hinode_state Hinode_enc Hinode_data".
iMod (is_inode_crash_prev_own with "Htxncrash [$Hinode_state Hinode_enc Hinode_data]") as "H".
iSplit; try (iIntros "? !>"); done.
repeat rewrite -> firstn_length_le by word.
replace (U64 (Z.of_nat (int.nat u))) with u by word.
iDestruct (struct_fields_split with "Hreply") as "Hreply".
iSplitR "Hinode_state Hinode_enc Hinode_data".
repeat rewrite -> firstn_length_le by word.
replace (U64 (Z.of_nat (int.nat u))) with u by word.
wp_apply (wp_LockMap__Release with "Hcrashlocked").
wp_apply (wp_LoadAt with "[Status Resok Resfail]").
iApply nfstypes_setattr3res_merge.
(* Simulate to get Q, commit failed *)
iInv "Hsrc" as ">Hopen" "Hclose".
iDestruct (map_valid with "Hsrcheap Hinode_state") as "%Hsrc_fh".
iDestruct (big_sepM_lookup with "Hnooverflow") as %Hnooverflow; eauto.
iDestruct ("Hfupd" with "[] HP") as "Hfupd".
iMod "Hfupd" as "[HP HQ]".
iMod ("Hclose" with "[Hsrcheap HP]").
iDestruct "Hcommit" as "[Hcommit _]".
wpc_frame "Hinode_state Hcommit".
iMod (is_inode_crash_prev_own with "Htxncrash [$Hinode_state $Hcommit]") as "H".
iModIntro; iSplit; try (iIntros "? !>"); done.
iDestruct (struct_fields_split with "Hreply") as "Hreply".
iSplitR "Hinode_state Hcommit".
wp_apply (wp_LockMap__Release with "Hcrashlocked").
wp_apply (wp_LoadAt with "[Status Resok Resfail]").
iApply nfstypes_setattr3res_merge.
iDestruct (is_jrnl_mem_durable with "Hjrnl_mem Hjrnl_durable") as "Hjrnl".
(* Not changing the length at all. *)
wpc_apply (wpc_Op__CommitWait with "[$Hjrnl $Htxncrash Hinode_enc Hinode_data]").
(* XXX is there a clean version of this? *)
generalize (jrnl_maps_to γtxn).
iIntros "[[H _]|[H0 H1]]"; iModIntro; iSplit; try done; try (iIntros "? !>").
iApply is_inode_crash_next.
iApply is_inode_crash_next.
iInv "Hsrc" as ">Hopen" "Hclose".
iDestruct (map_valid with "Hsrcheap Hinode_state") as "%Hsrc_fh".
iDestruct ("Hfupd" with "[] HP") as "Hfupd".
instantiate (3 := false).
iMod "Hfupd" as "[HP HQ]".
iMod ("Hclose" with "[Hsrcheap HP]").
wpc_frame "Hinode_state Hcommit".
iMod (is_inode_crash_prev_own with "Htxncrash [$Hinode_state $Hcommit]") as "H".
iSplit; try (iIntros "? !>"); done.
iDestruct (struct_fields_split with "Hreply") as "Hreply".
iSplitR "Hinode_state Hcommit".
wp_apply (wp_LockMap__Release with "Hcrashlocked").
wp_apply (wp_LoadAt with "[Status Resok Resfail]").
iApply nfstypes_setattr3res_merge.
(* Simulate to get Q, commit failed *)
iInv "Hsrc" as ">Hopen" "Hclose".
iDestruct (map_valid with "Hsrcheap Hinode_state") as "%Hsrc_fh".
iDestruct ("Hfupd" with "[] HP") as "Hfupd".
iMod "Hfupd" as "[HP HQ]".
iMod ("Hclose" with "[Hsrcheap HP]").
iDestruct "Hcommit" as "[Hcommit _]".
wpc_frame "Hinode_state Hcommit".
iMod (is_inode_crash_prev_own with "Htxncrash [$Hinode_state $Hcommit]") as "H".
iSplit; try (iIntros "? !>"); done.
iDestruct (struct_fields_split with "Hreply") as "Hreply".
iSplitR "Hinode_state Hcommit".
wp_apply (wp_LockMap__Release with "Hcrashlocked").
wp_apply (wp_LoadAt with "[Status Resok Resfail]").
iApply nfstypes_setattr3res_merge.