inode(4) DG/UX 4.30 inode(4)
NAME
inode - file node structure
SYNOPSIS
#include <ufs/diskformat.h>
DESCRIPTION
The inode table for a file system is distributed across the
disk: a table exists in each disk allocation region (DAR).
For more information about the file system layout, refer to
fs(4).
The file node's purpose is to provide access to data blocks
associated with the file. The data blocks are allocated in
chunks of contiguous physical blocks called data elements.
In the case that the file is less than the data element
size, the file is fragmented. In this case, the file has
only one data element and its size is determined by the
fragment exponent field. If the file grows, the fragmented
data element is copied to a full sized element, and the
allocation to the file will always be in data element sized
chunks, causing the actual size of the file to be less than
or equal to the blocks allocated to it.
Data elements are accessed directly or indirectly depending
on the size of the file. The file node has an array of
direct data elements, pointing to the first block of the
data element. If the size of the file is greater than the
number of direct data element pointers, then indirect access
is used.
Indirect data element access is provided through indexing.
An index structure consists of index blocks containing
pointers to data elements. Depending on the depth of the
index structure, index entries point to data elements or
other index blocks. There are three index structures rooted
in the file node; each of the three differs in the levels of
indexing. If the file node represents a directory, only the
first index level is used.
In the case of the first index structure, the pointer in the
file node points to the first block containing the index
entries (an index may span blocks); the entries at this
level point to data elements. The second index structure
points to the first block containing index entries. Each
index entry at this level points to the first block of an
index containing the same number of entries as the previous
level. These index entries contain pointers to data
elements. The third index structure is similar to the
previous two but has another level of indexing before the
index containing the data element pointers.
Licensed material--property of copyright holder(s) Page 1
inode(4) DG/UX 4.30 inode(4)
This expansion of index levels produces a tree, where the
leaves of the tree are data elements. The number at each
level multiplies itself by the number of index entries.
To access a data block, it must be determined if it is
accessible directly or through indexing. If direct access
is possible, the data element needs to be determined along
with the particular block within the data element. If the
block is deep enough in the file to require indexing, the
level of indexing must be determined by finding what range
of blocks each index covers. After the index structure is
determined, the path of entries through the index structure
is required.
The inode table in the DAR is made up of entries of the
following structure:
Licensed material--property of copyright holder(s) Page 2
inode(4) DG/UX 4.30 inode(4)
typedef struct
{
boolean_field_type is_allocated : 1;
boolean_field_type is_fragmented : 1;
field_type fragment_size_exponent : 3;
field_type des_exponent : 5;
field_type ies_exponent : 4;
field_type pad_to_double_word : 9;
field_type partial_block_byte_count : 9;
uint32e_type whole_block_count;
uint32e_type generation_number;
uint32e_type dar_index;
df_file_node_number_type space_parent;
uint32e_type maximum_space_usage;
uint32e_type current_space_usage;
uint32e_type maximum_file_node_usage;
uint32e_type current_file_node_usage;
df_file_mode_type mode;
uint16e_type user_id;
uint16e_type group_id;
int16e_type link_count;
df_time_type time_last_accessed;
df_time_type time_last_modified;
df_time_type time_attributes_last_changed;
union
{
struct
{
uint32e_type data[DF_DIRECT_ELEMENT_COUNT];
union
{
struct
{
uint32e_type index_array[DF_MAX_DIR_INDEX_LEVEL];
df_din_type din;
} directory;
struct
{
uint32_type index_array[DF_MAX_INDEX_LEVEL];
} regular;
} index;
} element_addresses;
struct
{
uint16e_type major_device_number;
uint16e_type minor_device_number;
byte8e_type pad_to_union_size[48];
} represented_device;
} contents;
byte8e_type reserved[DF_RESERVED_BYTES_PER_FILE_NODE];
} df_file_node_type;
Licensed material--property of copyright holder(s) Page 3
inode(4) DG/UX 4.30 inode(4)
is_allocated indicates whether this is a free file node or
not. If FALSE it is a free file node; if TRUE, then this is
a valid file node.
is_fragmented is TRUE when the first (and only) element of
the file is reduced in size from the data element size to
the fragment size specified by fragment_size_exponent;
otherwise, all data elements (if any) are the full data
element size and fragment_size_exponent is invalid.
fragment_size_exponent specifies, when valid, the size of
the fragmented data element which contains the file's data.
The size in blocks of the fragment is 2 raised to the
fragment_size_exponent power. It must be large enough to
fit the total size of the file in the fragment. Because all
fragments must fit into a single file system buffer, the
maximum fragment size is:
#define DF_MAX_FRAGMENT_SIZE 16
blocks, although the fragment_size_exponent field is large
enough to support fragment sizes up to 128 (2 ^ 7) blocks.
des_exponent specifies the data element size. The data
element size in blocks is 2 raised to the des_exponent
power. The maximum data element size is therefore 2 ^ 31
blocks. The maximum value for this field is:
#define DF_MAX_DES_EXPONENT 31
although it is also limited to the base 2 logarithm of the
largest power of 2 that is less than or equal to:
#define DF_USER_BLOCKS_PER_DAR(dar_size, file_nodes_per_dar)
ies_exponent specifies the index element size. The index
element size in blocks is 2 raised to the ies_exponent
power. The maximum index element size is therefore 2 ^ 15
blocks. The maximum value for this field is:
#define DF_MAX_IES_EXPONENT 15
although it is also limited to the base 2 logarithm of the
largest power of 2 that is less than or equal to:
#define DF_USER_BLOCKS_PER_DAR(dar_size, file_nodes_per_dar)
partial_block_byte_count is the count of the number of bytes
to the end of file following the last whole block. All
possible values, i.e., 0 to 511, are legal.
whole_block_count is the number of 512 byte blocks logically
Licensed material--property of copyright holder(s) Page 4
inode(4) DG/UX 4.30 inode(4)
in the file before EOF. The file size as reported by
stat(2) is:
((whole_block_count * 512) + partial_block_byte_count).
generation_number is incremented each time an inode is freed
and is kept valid on free nodes so that subsequent uses of
the same file node number are guaranteed to have different
UFID values.
dar_index is the current allocation hint (index of a DAR to
use for data and file node allocation). DAR indexes are
zero based.
space_parent is the parent file node number. In the file
node for the root of the filesystem, the value of
space_parent is:
#define DF_ROOT_FILE_NODE_NUMBER 2
therefore, the filesystem root is its own space parent.
maximum_space_usage is the maximum usage limit in blocks for
the file plus all its space descendants. It must be set to
UINT32_MAX for non-CPD directories and other non-directory
files, as well as for CPD's which have no allocation limit.
On the root of each filesystem, this limit is not applied to
the superuser.
current_space_usage is the current usage in blocks for the
file plus all its space descendants, if any. If not a CPD,
then it is the number of blocks actually used to store the
file's contents on disk, including both index and data
elements. For a CPD, it is that plus the
current_space_allocation fields of all files which name this
CPD as their space parent.
maximum_file_node_usage is the maximum file node usage limit
for the file plus all its space descendants. Must be
UINT32_MAX for non-CPD directories and other non-directory
files, as well as for CPDs with no file node allocation
limit. On the root of each filesystem, this limit is not
applied to the superuser. On all other CPD's it is applied
equally to all users.
current_file_node_usage is the current file node usage count
for the file plus all its space descendants. It must be 1
for non-CPD directories and other non-directory files. For
a CPD, it is 1 plus the current_file_node_usage fields of
all files which name this CPD as their space parent.
mode is the file's mode. Seestat(2).
Licensed material--property of copyright holder(s) Page 5
inode(4) DG/UX 4.30 inode(4)
user_id is user id of the file.
group_id is the group id of the file.
link_count is the number of links (directory entries) to the
file. Must be greater than zero.
time_last_accessed is the time the file's contents were last
accessed (i.e., read or executed).
time_last_modified is the time the file's contents were last
modified (i.e., written or truncated).
time_attributes_last_changed is the time one of the file's
attributes (mode, user_id, group_id, link_count,
child_count, etc.) was last changed.
contents is a union containing represented_device for
block-special or character-special files, and containing
element_addresses for all other file types.
represented_device is the device numbers of the device
represented by a character or block special file. The
padding bytes (pad_to_union_size) must be set to zero.
element_addresses are the disk addresses of the data
elements and index elements of the file. The "data" field
contains the addresses of the first:
#define DF_DIRECT_ELEMENT_COUNT 10
data elements in the file. The "index" field contains the
addresses of the first index element of each level for
regular files. For directory files, we only have 1 level of
indexing, with the other two index fields being used to
store the directory manager information.
Since all the file nodes in a DAR are not necessarily
allocated, a list of free file nodes must be maintained.
The head of the list is contained in each DAR entry. The
DAR entry contains the file node number of a file node in
the DAR, that file node should be unallocated and the
following structure contains the fields for a free file
node:
typedef struct
{
boolean_field_type is_allocated : 1;
df_file_node_number_type next_free_file_node_number;
uint32e_type generation_number;
byte8e_type pad_to_file_node_size[DF_FREE_FILE_NODE_PADDING];
} df_free_file_node_type;
Licensed material--property of copyright holder(s) Page 6
inode(4) DG/UX 4.30 inode(4)
is_allocated is TRUE when this is a valid file_node. If
FALSE, then this is a free file_node.
generation_number is kept valid on free nodes so that
subsequent uses of the same file node number are guaranteed
to have different UFID values.
next_free_file_node_number is the file node number of next
free file_node on the DAR free file_node list.
SEE ALSO
mkfs(1M), fsck(1M), stat(2), dg_stat(2), fs(4), System
Manager's Reference for the DG/UX System.
Licensed material--property of copyright holder(s) Page 7