diff --git a/UBIXFS.PAS b/UBIXFS.PAS index f8948a9..229070e 100755 --- a/UBIXFS.PAS +++ b/UBIXFS.PAS @@ -1,3 +1,7 @@ +// XXX ToDo +// in extendFile(), if allocBRun() fails, ask for small chunks instead of one large one +// ability to add attributes to the attr dir +// extension of attributes unit UbixFS; interface @@ -7,62 +11,62 @@ // open/fcntl - O_SYNC is only implemented on blocks devices and on files // located on an ext2 file system -const O_ACCMODE = 00000003; -const O_RDONLY = 00000000; -const O_WRONLY = 00000001; -const O_RDWR = 00000002; -const O_APPEND = 00000010; -const O_CREAT = 00000400; // not fcntl -const O_TRUNC = 00001000; // not fcntl -const O_EXCL = 00002000; // not fcntl -const O_LARGEFILE = 00004000; -const O_SYNC = 00100000; +const O_ACCMODE = 00000003; +const O_RDONLY = 00000000; +const O_WRONLY = 00000001; +const O_RDWR = 00000002; +const O_APPEND = 00000010; +const O_CREAT = 00000400; // not fcntl +const O_TRUNC = 00001000; // not fcntl +const O_EXCL = 00002000; // not fcntl +const O_LARGEFILE = 00004000; +const O_SYNC = 00100000; // O_NONBLOCK = 00200004; // HPUX has separate NDELAY & NONBLOCK */ //const O_NDELAY = O_NONBLOCK; -const O_NOCTTY = 00400000; // not fcntl */ -const FASYNC = 00020000; // fcntl, for BSD compatibility */ -const O_DIRECT = 00040000; // direct disk access hint - currently ignored */ -const O_DIRECTORY = 00010000; // must be a directory */ -const O_NOFOLLOW = 00000200; // don't follow links */ -const O_INVISIBLE = 04000000; // invisible I/O, for DMAPI/XDSM +const O_NOCTTY = 00400000; // not fcntl */ +const FASYNC = 00020000; // fcntl, for BSD compatibility */ +const O_DIRECT = 00040000; // direct disk access hint - currently ignored */ +const O_DIRECTORY = 00010000; // must be a directory */ +const O_NOFOLLOW = 00000200; // don't follow links */ +const O_INVISIBLE = 04000000; // invisible I/O, for DMAPI/XDSM -const F_DUPFD = 0; // dup -const F_GETFD = 1; // get f_flags -const F_SETFD = 2; // set f_flags -const F_GETFL = 3; // more flags (cloexec) -const F_SETFL = 4; -const F_GETLK = 5; -const F_SETLK = 6; -const F_SETLKW = 7; -const F_GETLK64 = 8; -const F_SETLK64 = 9; -const F_SETLKW64 = 10; +const F_DUPFD = 0; // dup +const F_GETFD = 1; // get f_flags +const F_SETFD = 2; // set f_flags +const F_GETFL = 3; // more flags (cloexec) +const F_SETFL = 4; +const F_GETLK = 5; +const F_SETLK = 6; +const F_SETLKW = 7; +const F_GETLK64 = 8; +const F_SETLK64 = 9; +const F_SETLKW64 = 10; // for F_[GET|SET]FL -const FD_CLOEXEC = 1; // actually anything with low bit set goes +const FD_CLOEXEC = 1; // actually anything with low bit set goes // for posix fcntl() and lockf() -const F_RDLCK = 01; -const F_WRLCK = 02; -const F_UNLCK = 03; +const F_RDLCK = 01; +const F_WRLCK = 02; +const F_UNLCK = 03; // for old implementation of bsd flock () -const F_EXLCK = 4; // or 3 -const F_SHLCK = 8; // or 4 +const F_EXLCK = 4; // or 3 +const F_SHLCK = 8; // or 4 // for leases -const F_INPROGRESS = 16; +const F_INPROGRESS= 16; // operations for bsd flock(), also used by the kernel implementation -const LOCK_SH = 1; // shared lock -const LOCK_EX = 2; // exclusive lock -const LOCK_NB = 4; // or'd with one of the above to prevent blocking -const LOCK_UN = 8; // remove lock +const LOCK_SH = 1; // shared lock +const LOCK_EX = 2; // exclusive lock +const LOCK_NB = 4; // or'd with one of the above to prevent blocking +const LOCK_UN = 8; // remove lock -const LOCK_MAND = 32; // This is a mandatory flock -const LOCK_READ = 64; // ... Which allows concurrent read operations -const LOCK_WRITE = 128; // ... Which allows concurrent write operations -const LOCK_RW = 192; // ... Which allows concurrent read & write ops +const LOCK_MAND = 32; // This is a mandatory flock +const LOCK_READ = 64; // ... Which allows concurrent read operations +const LOCK_WRITE = 128; // ... Which allows concurrent write operations +const LOCK_RW = 192; // ... Which allows concurrent read & write ops const INODE_NO_FLAG = $00000000; const INODE_IN_USE = $00000001; @@ -90,53 +94,53 @@ const SECTOR_SIZE = 1 shl SECTOR_SHIFT; type - int8 = shortInt; - int16 = smallInt; - int32 = longInt; + int8 = shortInt; + int16 = smallInt; + int32 = longInt; - uInt8 = byte; - uInt16 = word; - uInt32 = dWord; + uInt8 = byte; + uInt16 = word; + uInt32 = dWord; { Common Integer array definitions } type - int8ArrayPtr = ^int8Array; - int8Array = array[ 0..0 ] of int8; + int8ArrayPtr = ^int8Array; + int8Array = array[ 0..0 ] of int8; - int16ArrayPtr = ^int16Array; - int16Array = array[ 0..0 ] of int16; + int16ArrayPtr = ^int16Array; + int16Array = array[ 0..0 ] of int16; - int32ArrayPtr = ^int32Array; - int32Array = array[ 0..0 ] of int32; + int32ArrayPtr = ^int32Array; + int32Array = array[ 0..0 ] of int32; { Common Unsigned Integer array definitions } type - uInt8ArrayPtr = ^uInt8Array; - uInt8Array = array[ 0..0 ] of uInt8; + uInt8ArrayPtr = ^uInt8Array; + uInt8Array = array[ 0..0 ] of uInt8; - uInt16ArrayPtr= ^uInt16Array; - uInt16Array = array[ 0..0 ] of uInt16; + uInt16ArrayPtr = ^uInt16Array; + uInt16Array = array[ 0..0 ] of uInt16; - uInt32ArrayPtr= ^uInt32Array; - uInt32Array = array[ 0..0 ] of uInt32; + uInt32ArrayPtr = ^uInt32Array; + uInt32Array = array[ 0..0 ] of uInt32; type flock = object - lType:smallint; - lWhence:smallint; - lStart:integer; - lLen:integer; - lPID:integer; + lType : smallint; + lWhence : smallint; + lStart : integer; + lLen : integer; + lPID : integer; end; // flock type flock64 = object - lType:smallint; - lWhence:smallint; - lStart:int64; - lLen:int64; - lPID:integer; + lType : smallint; + lWhence : smallint; + lStart : int64; + lLen : int64; + lPID : integer; end; // flock64 (* TBlockRun = packed record @@ -160,50 +164,50 @@ *) PDiskSuperBlock = ^TDiskSuperBlock; TDiskSuperBlock = packed record - name : array[0..31] of char; - magic1 : int32; + name : array[ 0..31 ] of char; + magic1 : int32; - fsByteOrder : int32; + fsByteOrder : int32; // blockSize on disk - blockSize : uInt32; + blockSize : uInt32; // number of bits needed to shift a block number to get a byte address - blockShift : uInt32; + blockShift : uInt32; - numBlocks : int64; - usedBlocks : int64; + numBlocks : int64; + usedBlocks : int64; - inodeSize : uInt32; - magic2 : uInt32; + inodeSize : uInt32; + magic2 : uInt32; - blocksPerAG : uInt32; - AGShift : uInt32; - numAGs : uInt32; + blocksPerAG : uInt32; + AGShift : uInt32; + numAGs : uInt32; - flags : uInt32; + flags : uInt32; - logBlocks : TBlockRun; - logStart : int64; - logEnd : int64; + logBlocks : TBlockRun; + logStart : int64; + logEnd : int64; - magic3 : int32; - BAT : inodeAddr; - rootDir : inodeAddr; - indicies : inodeAddr; + magic3 : int32; + BAT : inodeAddr; + rootDir : inodeAddr; + indicies : inodeAddr; - pad : array[0..371] of byte; + pad : array[0..371] of byte; end; // TDiskSuperBlock PDataStream = ^TDataStream; TDataStream = packed record direct : array[0..DATASTREAM_DIRECT_BLOCKS-1] of TBlockRun; maxDirect : int64; - indirect : TBlockRun; maxIndirect : int64; - doubleIndirect: TBlockrun; maxDIndirect : int64; size : int64; + indirect : TBlockRun; + doubleIndirect: TBlockrun; blockCount : uInt32; end; // TDataStream @@ -213,13 +217,13 @@ nameSize : uInt16; dataSize : uInt16; dataType : treeTypes; - reserved : array[0..2] of uInt8; - name : array[0..0] of char; - function align(size:uInt32):uInt32; - function dataPtr:pointer; - function isEmpty:boolean; - function next:PSmallDataNode; - function size:uInt32; + reserved : array[ 0..2 ] of uInt8; + name : array[ 0..0 ] of char; + function align(size:uInt32):uInt32; + function dataPtr:pointer; + function isEmpty:boolean; + function next:PSmallDataNode; + function size:uInt32; end; // TSmallDataNode PUbixfsInode = ^TUbixfsInode; @@ -240,37 +244,37 @@ data : uPtr; {this was the etc field in bfs} blocks : TDataStream; smallData : TSmallDataNode; - function addAttr(attribute:PChar; attrType:treeTypes; buffer:pointer; count:uInt32):PSmallDataNode; - function delAttr(attribute:PChar; whichNode:PSmallDataNode):boolean; - function findAttr(attribute:PChar):PSmallDataNode; + function addAttr(attribute:PChar; attrType:treeTypes; buffer:pointer; count:uInt32):PSmallDataNode; + function delAttr(attribute:PChar; whichNode:PSmallDataNode):boolean; + function findAttr(attribute:PChar):PSmallDataNode; end; // TUbixfsInode PCacheNode = ^TCacheNode; TCacheNode = object public - address : int64; - lastUsed : int64; - data : pointer; - dataSize : uInt32; - dirty : boolean; - locked : boolean; - constructor init(_address, _lastUsed:int64; _dataSize:uInt32); - destructor done; + address : int64; + lastUsed : int64; + data : pointer; + dataSize : uInt32; + dirty : boolean; + locked : boolean; + constructor init(_address, _lastUsed:int64; _dataSize:uInt32); + destructor done; end; // TCacheNode PVNode = ^TVNode; TVNode = object - TID : uInt32; // Thread ID - iAddr : inodeAddr; - position : int64; - flags : uInt32; + TID : uInt32; // Thread ID + iAddr : inodeAddr; + position : int64; + flags : uInt32; end; // TVNode PVnid = ^TVnid; TVnid = object - refCount : uInt32; - iAddr : inodeAddr; - mode : uInt32; + refCount : uInt32; + iAddr : inodeAddr; + mode : uInt32; end; // TVnid PUbixFS = ^TUbixFS; @@ -361,7 +365,7 @@ // to determine how many blocks each blockRun uses. // vv DO NOT CHANGE vv // -const NUM_EXTENSION_BLOCKS = 4; // <--- don't change this +const NUM_EXTENSION_BLOCKS = 64; // <--- don't change this // ^^ DO NOT CHANGE ^^ // const NUM_CACHE_ENTRIES = 8192; // default max entries in block cache diff --git a/lists.pas b/lists.pas index fb90a74..62c917e 100755 --- a/lists.pas +++ b/lists.pas @@ -178,6 +178,7 @@ function FindPrev(var searchRec:BTreeSearchRec):boolean; function GetFirstKey(var searchRec:BTreeSearchRec):boolean; function GetKeyCount:uInt32; + function GetTreeHeight:uInt32; function GetLastKey(var searchRec:BTreeSearchRec):boolean; procedure PrintList(const filename:string); procedure PrintWholeTree(const filename:string); @@ -2118,6 +2119,11 @@ result := 0 end; // bTree.GetKeyCount +function bTree.GetTreeHeight; +begin + result := getHeight(); +end; // bTree.GetTreeHeight + function bTree.GetLastKey; begin with searchRec do