blob: d43be1ead8c5f851f566ff3cfb36d191af7ba86c [file]
{-# LANGUAGE ImplicitParams #-}
{-# LANGUAGE MultiWayIf #-}
{-# LANGUAGE TupleSections #-}
module Fsop (
module Fsop
, module WordArray
) where
import Control.Arrow
-- import Data.Array
import Data.Bits
import qualified Data.Map as M
import Data.Word
import Data.Void
import WordArray hiding (O)
type U8 = Word8
type U16 = Word16
type U32 = Word32
type U64 = Word64
type ErrCode = U32
type O = ErrCode
bilbyFsBlockShift = 12 :: U32
bilbyFsBlockSize = 4096 :: U32
ePerm = 1 :: ErrCode
eNoEnt = 2 :: ErrCode
eSrch = 3 :: ErrCode
eIntr = 4 :: ErrCode
eIO = 5 :: ErrCode
eNXIO = 6 :: ErrCode
eTooBig = 7 :: ErrCode
eNoExec = 8 :: ErrCode
eBadF = 9 :: ErrCode
eChild = 10 :: ErrCode
eAgain = 11 :: ErrCode
eAcces = 13 :: ErrCode
eNoMem = 12 :: ErrCode
eFault = 14 :: ErrCode
eNotBlk = 15 :: ErrCode
eBusy = 16 :: ErrCode
eExist = 17 :: ErrCode
eXDev = 18 :: ErrCode
eNoDev = 19 :: ErrCode
eNotDir = 20 :: ErrCode
eIsDir = 21 :: ErrCode
eInval = 22 :: ErrCode
eNFile = 23 :: ErrCode
eMFile = 24 :: ErrCode
eNoTty = 25 :: ErrCode
eTxtBsy = 26 :: ErrCode
eFBig = 27 :: ErrCode
eNoSpc = 28 :: ErrCode
eSPipe = 29 :: ErrCode
eRoFs = 30 :: ErrCode
eMLink = 31 :: ErrCode
ePipe = 32 :: ErrCode
eDom = 33 :: ErrCode
eRange = 34 :: ErrCode
eNameTooLong = 36 :: ErrCode
eNotEmpty = 39 :: ErrCode
eNoData = 42 :: ErrCode
eCrap = 66 :: ErrCode
eOverflow = 75 :: ErrCode
eRecover = 88 :: ErrCode
{-
|<-------------------- data ----------------------->|
+--------------+--------------+--------------+---------------
|xxxxxxxxxxxxxx|xxxxxxxxxxxxxx|xxxxxxxxxxxxxx|xxxxxxx........ -- (A)
+--------------+--------------+--------------+---------------
|xxxxxxxxxxxxxx|xxxxxxxxxxxxxx|xxxxxxxxxxxxxx|............... -- (B)
+--------------+--------------+--------------+---------------
|<- block 0 -->| 1 2 3
In case (A), limit = 3.
When block = 0,1,2 just read.
block = 3, because the size of the data is not perfectly aligned at the end, we still read.
block >= 4, return empty.
In case (B), limit = 3.
when block = 3, that's the special case. We return the old buffer unmodified.
-}
type Page = WordArray U8
type AfsState = M.Map VfsIno [Page]
data Obj = Obj { magic :: U32
, crc :: U32
, sqnum :: U64
, offs :: U32 -- in-mem only field
, len :: U32
, trans :: ObjTrans
, otype :: ObjType
, ounion :: ObjUnion
}
deriving (Eq, Ord, Show)
type ObjTrans = U8
type ObjType = U8
data ObjUnion = TObjDentarr ObjDentarr
| TObjInode ObjInode
| TObjData ObjData
| TObjDel ObjDel
| TObjSuper ObjSuper
| TObjSummary ObjSummary
| TObjPad ()
deriving (Eq, Ord, Show)
-- Their definitions shouldn't matter for this example
data ObjDentarr = ObjDentarr deriving (Eq, Ord, Show)
data ObjInode = ObjInode deriving (Eq, Ord, Show)
data ObjDel = ObjDel deriving (Eq, Ord, Show)
data ObjSuper = ObjSuper deriving (Eq, Ord, Show)
data ObjSummary = ObjSummary deriving (Eq, Ord, Show)
data ObjData = ObjData { oid :: ObjId, odata :: WordArray U8 }
deriving (Eq, Ord, Show)
type ObjId = U64
type VfsIno = U32
obj_id_inode_mk :: VfsIno -> ObjId
obj_id_inode_mk ino = (fromIntegral ino `shiftL` 32) .|. bilbyFsOidMaskInode
obj_id_data_mk :: VfsIno -> U32 -> ObjId
obj_id_data_mk ino blk = obj_id_inode_mk ino .|. bilbyFsOidMaskData .|. fromIntegral blk
inum_from_obj_id :: ObjId -> VfsIno
inum_from_obj_id oid = fromIntegral (oid `shiftR` 32)
bilbyFsOidMaskData :: U64
bilbyFsOidMaskData = fromIntegral bilbyFsObjTypeData `shiftL` fromIntegral bilbyFsXinfoShift
bilbyFsOidMaskInode :: U64
bilbyFsOidMaskInode = fromIntegral bilbyFsObjTypeInode `shiftL` fromIntegral bilbyFsXinfoShift
bilbyFsXinfoShift :: U64
bilbyFsXinfoShift = 29
bilbyFsObjTypeInode :: U8
bilbyFsObjTypeInode = 0
bilbyFsObjTypeData :: U8
bilbyFsObjTypeData = 1
type VfsSize = U64