blob: 0ff573e2e7380007941740038b9c6fe6b5f69472 [file]
include <gum/common/wordarray.cogent>
include <gum/common/array.cogent>
include <gum/common/rbt.cogent>
-- include <gum/kernel/linux/errno.cogent>
-- include <gum/kernel/linux/os.cogent>
-- //////////// kernel
eNoMem : ErrCode
eNoMem = 12
-- //////////// common
-- type SysState
-- type RR c a b = (c, <Success a | Error b>)
-- type ErrCode = U32
-- /////////// bilbyfs
bilbyFsFirstLogEbNum : U32
bilbyFsFirstLogEbNum = 2
type MountState = {
eb_recovery: U32,
eb_recovery_offs: U32,
super : ObjSuper,
obj_sup: Obj take (ounion),
super_offs: U32,
vol : UbiVolInfo,
dev : UbiDevInfo,
no_summary : Bool
}
type ObjSuper = { nb_eb : U32
, eb_size : U32
, io_size : U32
, nb_reserved_gc : U32
, nb_reserved_del : U32
, cur_eb : U32
, cur_offs : U32
, last_inum : U32
, next_sqnum : U64
}
type Obj = {
magic : U32,
crc : U32,
sqnum : U64,
offs : U32, -- in-mem only field
len : U32,
-- , pad1 : U8
-- , pad2 : U8
trans : ObjTrans,
otype : ObjType,
ounion : ObjUnion
}
type ObjDel = #{ id : ObjId } take ()
type ObjDentarr = {
id : ObjId,
nb_dentry : U32,
entries : Array ObjDentry
}
type ObjDentry = {
ino : U32,
dtype : U8,
-- pad : U8,
nlen : U16,
name : WordArray U8
}
type ObjInodeFlags = U32
type ObjInode = {id : ObjId
, size : U64
, atime_sec : U64
, ctime_sec : U64
, mtime_sec : U64
, nlink : U32
, uid : U32
, gid : U32
, mode : U32
, flags : ObjInodeFlags
-- , pad : U64
}
type ObjSummary = {
nb_sum_entry : U32, -- nb_sum_entry must be <= wordarray_length sum.entries
-- the wordarray is ususally larger than what's get serialised.
-- Using an array for this would be too inefficient.
entries : WordArray ObjSumEntry, -- only @nb_sum_entry element get serialised on medium
-- At the very end of the summary is the offset of the summary itself.
sum_offs : U32
}
type ObjSumEntry = #{
id : U64,
sqnum : U64,
len : U32,
del_flags_and_offs : U32,
count : U16 -- nb of object covered by the deletion object
}
type ObjUnion = <TObjDentarr ObjDentarr
| TObjInode ObjInode
| TObjData ObjData
| TObjDel ObjDel
| TObjSuper ObjSuper
| TObjSummary ObjSummary
| TObjPad ()>
type ObjData = #{
id : ObjId,
odata : WordArray U8
}
type ObjType = U8
type ObjTrans = U8
type ObjId = U64
type ObjIdDentarr = U64
type ObjIdData = U64
type ObjIdInode = U64
-- ////////// ubi
type UbiVolInfo
type UbiDevInfo
-- /////////// fsm
type FsmState = { nb_free_eb : U32
, used_eb : WordArray U8
, dirty_space : WordArray U32
, gim : Rbt ObjId GimNode }
type GimNode = #{ count : U16, sqnum : U64 }
type RbtGimNode = RbtNode ObjId GimNode
fsm_init : (SysState, MountState!, FsmState take (..)) -> RR SysState FsmState (ErrCode, FsmState take(..))
fsm_init(ex, mount_st, fsm_st) =
let nb_eb = mount_st.super.nb_eb
in wordarray_create[U8] (ex, nb_eb)
| Error ex -> (ex, Error (eNoMem, fsm_st))
| Success (ex, used_eb) ->
wordarray_create[U32] (ex, nb_eb)
| Error ex ->
let ex = wordarray_free[U8](ex, used_eb)
in (ex, Error (eNoMem, fsm_st))
| Success (ex, dirty_space) ->
rbt_create[ObjId,GimNode] ex
| Error ex ->
let ex = wordarray_free[U8](ex, used_eb)
and ex = wordarray_free[U32](ex, dirty_space)
in (ex, Error (eNoMem, fsm_st))
| Success (ex, gim) ->
let nb_free_eb = mount_st.super.nb_eb - bilbyFsFirstLogEbNum
in (ex, Success (fsm_st {used_eb, dirty_space, gim, nb_free_eb}))