Inode_table Module Interface Specification

Informal Introduction

Inode table is a global system table. It contains i-nodes. Each i-node
corresponds to one Unix 'generic' file (being either directory or regular file).
I-node is identified by the i-node number. Each file may be accessed by different
names stored in different directories - they are called 'links'. The number of
links is stored in the file i-node; each time the file is deleted, the link count
is decremented by one. When the link count is decremented to zero, the file is
removed from disk and its i-node is deleted from the i-node table.

(0) CHARACTERISTICS

-type specified: inodetable

-features: non-deterministic, non-parameterized

-foreign types: genericfile, global

(1) SYNTAX

ACCESS-PROGRAMS

Program Name
Arg#1Arg#2Arg#3Result Type
CREATEinodetable:VOint:VRgenericfile:V 
CHANGEinodetable:VOint:Vgenericfile:V 
INCCOUNTERinodetable:VOint:V   
DECCOUNTERinodetable:VOint:V   
GETGENFILEinodetable:Vint:V  genericfile
ROOTDIRinodetable:V    int
ISFULLinodetable:V    bool

(2) CANONICAL TRACES

canonical(T) n:<int>; m[0]..m[n]:<int>; k[0]..k[n]:<int>; c[0]..c[n]:<int>; g[0]..g[n]:<genericfile>-1 n n < global::G_inode_table_size() -1 m[n] 0 k[0] i:<int>0 i i < n [-1 m[i] k[i] < k[i + 1]] [T = [CREATE(*, (*1,c[i]) k[i], g[i]).[INCCOUNTER(*, k[i])]j=0..m[i]]i=0..n ]

AUXILIARY FUNCTIONS

interrorval: <int>

interrorval() = -1

inodetablesize: <inodetable> <int>

inodetablesize(I) =

ConditionValue
I = _ 0
! I1:<inodetable>; k,m,c:<int>; g:<genericfile>0 k -1 m [I = I1.CREATE(*, (*1,c) k, g).[INCCOUNTER(*, k)]i=0..m ]k + 1

isfull: <inodetable> <bool>

isfull(I) = count(I, "CREATE") = global::G_inodetable_size()

getcounter: <inodetable> × <int> <int>

getcounter(I, k) =

ConditionValue
k < 0 k global::G_inodetable_size()interrorval()
¬ ! I1,I2:<inodetable>; m,c:<int>; g:<genericfile>-1 m [I = I1.CREATE(*, (*1,c) k, g).[INCCOUNTER(*, k)]i=0..m.I2 0 k k < global::G_inodetable_size()]0
! I1,I2:<inodetable>; m,c:<int>; g:<genericfile>-1 m [I = I1.CREATE(*, (*1,c) k, g).[INCCOUNTER(*, k)]i=0..m.I2 0 k k < global::G_inodetable_size()]m + 2

exists: <inodetable> × <int> <bool>

exists(I, k) = getcounter(I, k) 1

getgenfile: <inodetable> × <int> <genericfile>

getgenfile(I, k) =

ConditionValue
¬exists(I, k)genericfile::_
exists(I, k)g0 where I1,I2:<inodetable>; g0:<genericfile>; c:<int> [I = I1.CREATE(*, (*1,c) k, g0).I2 ]

isonpath: <inodetable> × <int> × <int> <bool>

isonpath(I, dir, gf) = n:<int>; p[1]..p[n]:<string>; d[0]..d[n]:<int>; g[0]..g[n - 1]:<genericfile> [dir = d[0] i:<int>1 i i n [exists(I, d[i - 1]) g[i - 1] = getgenfile(I, d[i - 1]) genericfile::type(g[i - 1]) = global::t_dir() genericfile::exists(g[i - 1], p[i]) genericfile::getinodetableindex(g[i - 1], p[i]) = d[i] ] d[n] = gf ]

isrootdir: <inodetable> × <int> <bool>

isrootdir(I, dir) = exists(I, dir) genericfile::getinodetableindex(getgenfile(I, dir), "..") = dir

rootdir: <inodetable> <int>

rootdir(I) =

ConditionValue
¬ ! dir:<int> [isrootdir(I, dir)]interrorval()
! dir:<int> [isrootdir(I, dir)]dir

nodetype: <inodetable> × <int> <int>

nodetype(I, k) = genericfile::type(getgenfile(I, k))

(3) SEMANTICS

ACCESS-PROGRAMS

Legality(CREATE((n, I), (k, c), g)) =

ConditionValue
¬isfull(I)%legal%
isfull(I)%no more free position%

CREATE((n, I) , (k, c) k0, g) = I1.CREATE(*, (*1,c) k0, g).I2 where I1,I2:<inodetable> [I = I1.I2 canonical(I1.CREATE(*, (*1,c) k0, g).I2)]

CREATE((n, I), (k, c) r, g) | ¬exists(I, r)

Legality(CHANGE((n, I), k, g)) =

ConditionValue
k < 0 k global::G_inodetable_size()%invalid argument%
0 k k < global::G_inodetable_size() ¬exists(I, k)%referenced inode table position doesn't exist%
exists(I, k)%legal%

CHANGE((n, I) , k, g) = newI where I1,I2,newI:<inodetable>; g0:<genericfile>; m,c:<int> [-1 m I = I1.CREATE(*, (*1,c) k, g0).[INCCOUNTER(*, k)]i=0..m.I2 newI = I1.CREATE(*, (*1,c) k, g).[INCCOUNTER(*, k)]i=0..m.I2 ]

Legality(INCCOUNTER((n, I), k)) =

ConditionValue
k < 0 k global::G_inodetable_size()%invalid argument%
0 k k < global::G_inodetable_size() ¬exists(I, k)%referenced inode table position doesn't exist%
exists(I, k)%legal%

INCCOUNTER((n, I) , k) = newI where I1,I2,newI:<inodetable>; g0:<genericfile>; m,c:<int> [-1 m I = I1.CREATE(*, (*1,c) k, g0).[INCCOUNTER(*, k)]i=0..m.I2 newI = I1.CREATE(*, (*1,c) k, g0).[INCCOUNTER(*, k)]i=0..m + 1.I2 ]

Legality(DECCOUNTER((n, I), k)) =

ConditionValue
k < 0 k global::G_inodetable_size()%invalid argument%
0 k k < global::G_inodetable_size() ¬exists(I, k)%referenced inode table position doesn't exist%
exists(I, k)%legal%

DECCOUNTER((n, I) , k) =

ConditionValue
! m,c:<int>0 m [I = I1.CREATE(*, (*1,c) k, g0).[INCCOUNTER(*, k)]i=0..m.I2 ]I1.CREATE(*, (*1,c) k, g0).[INCCOUNTER(*, k)]i=0..m - 1.I2
c:<int> [I = I1.CREATE(*, (*1,c) k, g0).I2 ]I1.I2
where I1,I2:<inodetable>; g0:<genericfile> [true]

Legality(GETGENFILE(I, k)) = %legal%

GETGENFILE(I, k) = getgenfile(I, k)

Legality(ROOTDIR(I)) = %legal%

ROOTDIR(I) = rootdir(I)

Legality(ISFULL(I)) = %legal%

ISFULL(I) = isfull(I)