fs
Purpose
Contains the format of a file system volume.
Synopsis
#include <sys/types.h>
#include <sys/param.h>
#include <sys/filsys.h>
Description
A file system storage volume has a common format for
certain vital information. A volume is divided into a
number of logical blocks, 512-byte blocks for diskette
and 2048-byte blocks for disks. The term block here
refers to the unit of disk space allocation, which is
some multiple of 512 bytes. The 512-byte unit is used to
report or specify file sizes in all commands and subrou-
tines, but here the term refers to a cluster of one or
more such units. RT PC supports two similar but distinct
file system formats, both of which are described by the
following text.
The first format uses the byte order and integer size of
the RT PC processing unit. The second format is compat-
ible with the PC/IX file system format, which is based on
the IBM PC-XT processing unit architecture. There are
several differences between the two file system formats:
the block size is 2048 bytes in the native file system
format and 512 bytes in the other, and the definition of
the superblock is different between the two. The number
and order of bytes within multi-byte data are different,
and the processing units impose different restrictions on
the alignment of 4-byte data. These last two differences
affect fields within the superblock, i-node numbers
within directories, and logical block numbers within
i-nodes and indirect blocks.
The mkfs application makes a file system of the second
format only when the file system device is a diskette.
Logical block 0 is unused and available to contain a
bootstrap program or other information. Logical block 1
is the superblock.
The format of a native-format file system superblock
follows.
#define FSfixsz 112 / * Fixed-format region is 112 bytes long */
typedef struct filsys
{ /* basic file system parameters - initialized when FS is created */
char s_magic[4]; /* magic number: FSmagic = 0xdf817eb2 */
char s_flag[4]; /* flag word (see below) */
daddr_t s_fsize; /* size in blocks of entire file system */
ushort s_bsize; /* block size (in bytes) for this filsys */
ushort s_isize; /* size (in blocks) of i-list and overhead */
short s_cyl; /* number of blocks per cylinder */
short s_skip; /* block interleaving factor */
short s_nicfree; /* number of slots in block free list */
short s_nicino; /* number of slots in free i-node list */
short s_sicfree; /* byte offset to start of block free list */
short s_sicino; /* byte offset to start of free i-node list */
char s_fname[6]; /* name of this file system */
char s_fpack[6]; /* name of this volume */
short s_nicfrag; /* number of slots in fragment table */
short s_sicfrag; /* byte offset to start of fragment table */
daddr_t s_swaplo; /* start of swap area (currently unused) */
daddr_t s_nswap; /* number of block swap area (currently unused) */
char s_rsvd[36]; /* reserved - must be zero */
/* current file system state information, values change over time */
ushort s_tffrag; /* number of fragmented files (currently unused) */
ushort s_tbfrag; /* number of fragmented blocks (currently unused) */
short s_findex; /* fragment allocation index (currently unused */
char s_fmod; /* superblock modified flag */
char s_ronly; /* mounted read-only flag */
daddr_t s_tfree; /* total free blocks */
char s_flock; /* lock during free list manipulation */
char s_ilock; /* lock during i-list manipulation */
short s_nfree; /* number of addresses in s_free */
ino_t s_tinode; /* total free inodes */
short s_ninode; /* number of inodes in s_inode */
time_t s_time; /* time of last superblock update */
/*
* TOTAL LENGTH OF FIXED-FORMAT REGION: 112 bytes
*
* All variable length fields appear beyond this point, and are
* described and pointed to by information in the fixed format
* portion of the superblock:
*
* daddr_t s_free[s nicfree];<free block list>
* ino_t s_inode[s nicino];<free I-node list>
* frag_t s_frag[s_nicfrag];<fragment table>
*
* Macros defined below allow access to these tables.
*/
union /* Variable-format */
{ char su_var [BSIZE-FSfixsz];
struct
{ daddr_t su_free[NICFREE];
ino_t su_inode[NICINOD];
} su_ovly;
} s_u;
} filsys_t;
#define s_free s_u.su_ovly.su_free
#define s_inode s_u.su_ovly.su_inode
#define s_var s_var
#define s_n s_cyl /* for compatibility with old systems */
#define s_m s_skip
#define FSmagic "\337\201\176\262" /* octal magic number for file systems */
/* hex equivalent value for FSmagic number above is \df\81\7e\b2 */
#define s_cpu s_flag[0] /* Target cpu type code (same as in a.out files) */
#define s_type s_flag[3] /* File system type code (block size) */
#define Fs1b 1 /* 512 byte blocksize file system */
#define Fs2b 2 /* 1024 byte blocksize */
#define Fs4b 3 /* 2048 byte blocksize */
#define Fs8b 4 /* 4096 byte blocksize */
/*
* Notes on s_fmod field:
* This field is intended to be a three state flag with the third
* state being a sticky state. The three states are:
*
* 0 = file system is clean and unmounted
* 1 = file system is mounted
* 2 = file system was mounted when dirty
*
* If you merely mount and unmount the file system, the flag
* toggles back and forth between states 0 and 1. If you ever
* mount the file system while the flag is in state 1 then it
* goes to state 2 and stays there until you run fsck.
* The only way to clean up a corrupted file system (and change
* the flag from state 2 back to state 0) is to run fsck.
* The bit above this tri-state (i.e. 04, FM_SDIRTY) is only used
* in memory. It is never written to disk.
*/
#define FM_CLEAN 00 /* File system is clean and unmounted */
#define FM_MOUNT 01 /* File system is mounted cleanly */
#define FM_MDIRTY 02 /* File system was dirty when last mounted */
#define FM_SDIRTY 04 /* Superblock is dirty; this bit is not written */
#define FMOD(x) ((x)==0?1:2)
#define FCLEAN(x) ((x)==2?2:0)
/*
* Macros for accessing elements in the variable-format region of the
* superblock. "sbp" is a pointer to superblock, and "n" gives
* the index of the element to be fetched.
*/
/* FREEino() -- Finds the nth element in the free I-node list. */
/* Each element of the free I-node list is of type "ino_t". */
#define FREEino(sbp,n) \
(((ino_t *)((char *)(sbp)+(sbp)->s_sicino))[n])
/* FREEblk() -- Finds the nth element in the free block list. Each */
/* element of the free block list is of type "daddr_t". */
#define FREEblk(sbp,n) \
(((daddr_t *)((char *)(sbp)+(sbp)->s_sicfree))[n])
/* we have a NEW Format superblock */
#define _s_NEWF
The format of a PC/IX-format file system superblock is:
/*
* Structure of the superblock
*/
struct filsys
{
ushort s_isize; /* size in blocks of i-list */
daddr_t s_fsize; /* size in blocks of entire volume */
short s_nfree; /* number of address in s_free */
daddr_t s_free[NICFREE]; /* free block list */
short s_ninode; /* number of inodes in s_inode */
ino_t s_inode[NICINOD]; /* free I-node list */
char s_flock; /* lock during free list manipulation */
char s_ilock; /* lock during i-list manipulation */
char s_fmod; /* superblock modified flag */
char s_ronly; /* mounted read-only flag */
time_t s_time; /* last superblock update */
short s_dinfo[4]; /* device information */
daddr_t s_tfree; /* total free blocks */
ino_t s_tinode; /* total free i-nodes */
char s_fname[6]; /* file system name */
char s_fpack[6]; /* file system pack name */
long s_fill[13]; /* fill out to 512 bytes */
daddr_t s_swaplo; /* start of swap area */
daddr_t s_nswap; /* number of blocks of swap */
long s_magic; /* magic number for file systems */
long s_type /* file system type - cluster size */
};
/*
* macros to give more meaningful names to dinfo fields
*/
#define s_m s_dinfo[0] /* modulo factor in superblock */
#define s_n s_dinfo[1] /* cylinder size in superblock */
#define s_bsize s_dinfo[2] /* block size for this file system */
If the latter superblock structure is compiled into a program, the native
compiler adds pad bytes to force long type data to be aligned on an address
that is a multiple of 4. A program that attempts to manipulate the PC/IX
format superblock must redeclare the values in a manner that does not change
the given alignment and then change data references appropriately.
The parameters NICFREE and NICINOD, the number of in-core free blocks and
free i-nodes, respectively, are defined in the system include file,
<sys/param.h>, as are BSIZE (the number of bytes in a block), and DIRSIZ (the
number of bytes in a simple file name).
The s_isize field is the number of the first data block after the i-list; the
starts just after the superblock (in block 2); thus the i-list is s_isize
minus 2 blocks long. The s_fsize field is the total number of blocks in the
file system. These numbers are used by the system to check for bad block
numbers; if an block number that cannot exist is allocated from the free list
or is freed, a message is sent to the system console. Moreover, the free
array is cleared, to prevent further allocation from a presumably corrupted
free list.
The s_bsize field contains the number of bytes in a file system block.
The s_cyl and s _skip fields contain parameters that control the organization
of the free-block list. The s_cyl field contains the number of blocks per
cylinder; s_skip is the interleave factor. Free-list interleaving is
described by the mkfs application. In the PC/IX format file system, these
fields are referenced using macros called s_n and s_m, respectively.
The s_nicfree and s_nicino fields contain the values of NICFREE and NICINO
(sizes of the s_free and s_inode arrays). The s_sicfree and s_sincino fields
contain the byte offset from the start of the superblock of s_free and
s_inode arrays. These numbers are provided to facilitate the writing of
BSIZE independent file system management utilities. These fields are present
only in the native format file system.
The free list for each volume is maintained as follows. The s_free array
contains, in s_free[1], . . . , s_free[s nfree-1], the block numbers of up
to NICFREE-1 free-blocks. The s_free[0] value is the block number of the
head of chain of blocks constituting the free list. The first long in each
free-chain block is the number (up to NICFREE) of free-block numbers listed
in the next NICFREE longs of this chain member. The first of these block
numbers is the link to the next member of the chain. To allocate a block:
decrement s_nfree, and the new block is s_free [s_nfree]. If the new block
number is 0, there are no blocks left. This an error condition. If s_nfree
became 0, read the block named by the new block number, replace s_nfree by
its first word, and copy the block numbers in the next NICFREE longs into the
s_free array. To free a block, check whether s_nfree is NICFREE; if so, copy
s_nfree and the s_free array into it, write it out, and set s_nfree to 0. In
any event, set s_free[s_nfree] to the freed block's number and increment
s_nfree.
The value of s_tfree is the total free-blocks available in the file system.
The value s_ninode is the number of free i-numbers in the s_inode array. To
allocate an i-node: if s_ninode is greater than 0, decrement it and return
s_inode[s_ninode]. If it was 0, read the i-list and place the numbers of up
to NICINOD free i-nodes into the s_inode array, then try again. To free an
i-node, provided s_ninode is less than NICINOD, place its number into
[s_ninode] and increment s_ninode. If s_ninode is already NICINOD, do not
bother to enter the freed i-node into any table. This list of in-nodes
serves only to speed up the allocation process. The i-node itself indicates
whether it is free.
The value of s_tinode is the total number of free i-nodes available in the
file system.
The s_fmod field is a flag to indicate the cleanliness of the file system. A
value of 0 indicates that the file system has been cleanly unmounted. When-
ever a file system is mounted, this flag is checked and a warning message is
printed if the s_fmod flag is non-zero. When a clean file system is mounted,
the s_fmod flag is changed to a value of 1. When an unclean file system is
mounted, s_fmod is set to 2. When a file system is unmounted, the s_fmod
flag is reset to 0 only if it has the value 1. Thus, a file system whose
s_fmod flag is 0 is very likely to be clean, and a file system whose s_fmod
flag is 2 is likely to have problems.
The s_ronly field is a flag indicating that the file system has been mounted
read only. This flag is maintained in memory only, its value on disk is not
valid.
The value of s_time is the last time the superblock of the file system was
changed, (in seconds since 00:00 Jan. 1, 1970 (GMT)).
s_fname is the name of the file system and s_fpack is the name of the device
on which it resides.
The s_flock and s_ilock flags are maintained in the copy of the file system
in memory while it is mounted; their values on disk are not valid.
The s_fill, s_swaplo, and s_nswap fields are not used on this system.
I-numbers begin at 1, and the storage for i-node 1 begins in the first byte
of block 2. I-node 1 is reserved for a file without a name. This i-node is
used by the mkfs application to put the numbers of defective blocks (blocks
with physical flaws) to prevent them from being allocated to other files.
I-node 2 is reserved for the root directory of the file system. No other
i-number has a built-in meaning. I-nodes are 64 bytes long, so BSIZE / 64 of
them fit into a block. Each i-node represents one file. For the format of
an i-node and its flags, see "inode."
Files
/usr/include/sys/filsys.h
/usr/include/sys/stat.h
Related Information
In this book: "inode" and "param.h."
The fsck, fsdb, and mkfs programs in AIX Operating System Commands Reference.