Physical File Structure

  1. Network File System
  2. File System
  3. Pipes

Network File System

Taken from man NFS

The Network File System, or NFS, allows a client workstation to perform transparent file access over the network. using it, a client workstation can operate on files that reside on a variety of servers, server architectures and across a variety of operating systems. Client file access calls are converted to NFS protocol requests, and are sent to the server over the network. The server receives the request, performs the actual file system operation, and sends a response back to the client.
A server can grant access to a specific file system to certain clients by adding an entry for that file system to the server's /etc/exports file and running exportfs(8).
A client gains access to that file system with the mount(2V) system call, which requests a file handle for the file system itself. Once the file system is mounted by the client, the server issues a file handle to the client for each file (or directory) the client accesses or creates.
A server may also be a client with respect to file systems it has mounted over the network, but its clients cannot gain access to those file systems. Instead, the client must mount a file system directly from the server on which it resides.
The user ID and group ID mappings must be the same between client and server. However, the server maps uid 0 (super-user) to uid -2 before performing access checks for a client. This inhibits superuser privileges on remote file systems. This can be changed by the use of the "anon" export option.

File System

A file system has the following structure:

Pipes

Pipes allow transfer of data between processes in a first-in-first-out manner (FIFO), and they also allow synchronization of process execution. Their implementation allows processes to communicate even though they do not know what processes are on the other end of the pipe. The traditional implementation of pipes uses the file system for data storage. (Bach 111)
There are two kinds of pipes, named pipes and unnamed pipes. The two are identical except for the way that a process initially accesses them. Processes use the open system call for named pipes but the pipe system call for an unnamed pipe. Later, processes use the read, write and close system calls when manipulating pipes.

Opening a Named Pipe

A named pipe is a file whose semantics are the same of those of an unnamed pipe except that it has a directory entry and is accessed by a path name. (Bach 113) Named pipes are opened the same way that regular files are opened, therefore processes that are not closely related can communicate. Named pipes permanently exist in the file system hierarchy, but unnamed pipes are not. When all processes are done using the pipe, the kernel reclaims its inode.
A process that opens the named pipe for reading will sleep until another process opens the named pipe for writing and vice versa. Depending on whether process opens the named pipe for reading or writing, the kernel awakens other processes that were asleep, waiting for a writer or reader process on the named pipe. If a process opens a named pipe for reading and a writing process exists, the open call completes.

Reading and Writing Pipes

A pipe should be viewed as if processes write into one end of the pipe and read from the other end. (Bach 113) Processes access data from a pipe in FIFO (first-in-first-out) manner, meaning that data is written into a pipe is the order that it is read from the pipe. The number of processes reading from a pipe do not have to equal the number of processes writing the pipe; if the number of readers or writers is greater than 1, they must coordinate use of the pipe with other mechanisms. (Bach 113) The kernel accesses the data for a pipe exactly the same way it accesses data for a regular file. It stores the data on the pipe device and assigns blocks to the pipe when needed during write calls. The kernel manipulates the direct blocks of the inode as a circular queue, maintaining read and write pointers internally to preserve the FIFO order. (Bach 114)
When a process reads a pipe, it checks if the pipe is empty or not. If the pipe contains data, the kernel reads the data from the pipe as if the pipe were a regular file, following the regular algorithm for read. But if the initial offset is the pipe read pointer stored in the inode, indicating the extent of the previous read. After reading each block, the kernel decrements the size of the pipe according to the numbers of bytes it read. When the read system call completes, the kernel awakens all sleeping writer processes and saves the current read offset in the inode but not in file table entry. (Bach 115)
If a process attempts to read more data than is in the pipe, the read will complete successfully after returning all data currently in the pipe, even though it does not satisfy the user count. If the pipe is empty, the process will typically sleep until another process writes data into the pipe, at which time all sleeping processes that were waiting for data wake up and race to read the pipe. But if a process opens a named pipe with the no delay option, it will return immediately from a read if the pipe contains no data. (Bach 115)
If a process writes a pipe and the pipe cannot hold all the data, the kernel marks the inode and goes to sleep waiting for data to drain from the pipe. When another process reads from the pipe later reads from the pipe, the kernel will notice that the processes are asleep waiting for data to drain from the pipe, and it will awaken them. The only exception is when a process writes an amount of data greater than the pipe capacity; the kernel writes as much data as possible to the pipe and puts the process to sleep until more room becomes available. (Bach 115)

Closing Pipes

"When closing a pipe, a process follows the same procedure it would follow for closing a regular file, except that the kernel does special processing before releasing the pipe's inode. The kernel decrements the number of pipe readers or writers, according to the type of the file descriptor. If the count of writer drops to 0 and there are processes asleep waiting to read data from the pipe, the kernel awakens them, and they return from their read calls without reading any data. If the count of reader processes drops to 0 and there are processes asleep waiting to write data to the pipe, the kernel awakens them and sends them a signal to indicate an error condition. If no reader or writer processes access the pipe, the kernel frees all its data blocks and adjusts the inode to indicate that the pipe is empty." (Bach 116)

Previous Contents Next