A file system is an abstraction provided by an operating system to users for them to store data aggregates of all sorts (program source code, executable binary, document source and formatted output, etc, etc), using names for them which make sense to the users. The actual storage itself typically uses secondary storage (generally disk).
The file system takes the actual storage blocks (normally identified with a block number) on a disk, and starts by allocating enough of them to hold a file of the desired size, and then makes a record of which blocks belong to which files. It also has to know which blocks are 'free', and available for allocation - a variety of data structures are used to hold this information (free lists, free arrays, etc).
A file system also normally includes directories, which are collections of related files. Modern file systems are usually a tree-structured hierarchy; i.e. a directory can also include other directories, the whole being structured as a tree descending from a root directory.
The typical operations provided by the operating system include:
- opening and closing files;
- reading and writing them;
- moving to a different position in a file prior to reading/writing;
- creating new files, and deleting existing ones;
- moving a file to a new location.
Two main approaches have been used to organize file systems internally.
Originally, the information as to which blocks were part of a file was kept in the directory, along with other meta-information about the file (date last modified, etc); this approach was used in early operating systems such as Multics, as well as later ones like Windows.
UNIX started a new approach, in which most information about a file (particularly, which blocks were used to hold it) was kept in a separate structure (called an inode in UNIX); directories (usually implemented as an abstraction on top of the previous layer) only held mappings from file-names (visible to users) to inode numbers.