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
Arg#1 | Arg#2 | Arg#3 | Result Type | CREATE | inodetable:VO | int:VR | genericfile:V | | CHANGE | inodetable:VO | int:V | genericfile:V | | INCCOUNTER | inodetable:VO | int:V | | | DECCOUNTER | inodetable:VO | int:V | | | GETGENFILE | inodetable:V | int:V | | genericfile | ROOTDIR | inodetable:V | | | int | ISFULL | inodetable: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) =
Condition | Value |
---|---|
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) =
Condition | Value |
---|---|
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) =
Condition | Value |
---|---|
¬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) =
Condition | Value |
---|---|
¬ ! 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-PROGRAMSLegality(CREATE((n, I), (k, c), g)) =
Condition | Value |
---|---|
¬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)) =
Condition | Value |
---|---|
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)) =
Condition | Value |
---|---|
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)) =
Condition | Value |
---|---|
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) =
Condition | Value |
---|---|
! 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 |
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)