Online Book Reader

Home Category

Beautiful Code [220]

By Root 5356 0

First, the process is very iterative. As the requirements of the kernel change, and the systems on which it runs also change, the developers have found ways to abstract different parts of the model to make it more efficient where it is needed. This is responding to a basic evolutionary need of the system to survive in these environments.

Second, the history of device handling shows that the process is extremely collaborative. Different developers come up independently with ideas for improving and extending different aspects of the kernel. Through the source code, others can then see the goals of the developers exactly as they describe them, and then help change the code in ways the original developers never considered. The end result is something that meets the goals of many different developers by finding a common solution that would not have been seen by any one individual.

These two characteristics of development have helped Linux evolve into the most flexible and powerful operating system ever created. And they ensure that as long as this type of development continues, Linux will remain this way.

Another Level of Indirection > From Code to Pointers

17. Another Level of Indirection

Diomidis Spinellis

All problems in computer science can be solved by another level of indirection," is a famous quote attributed to Butler Lampson, the scientist who in 1972 envisioned the modern personal computer. The quote rings in my head on various occasions: when I am forced to talk to a secretary instead of the person I wish to communicate with, when I first travel east to Frankfurt in order to finally fly west to Shanghai or Bangalore, and—yes—when I examine a complex system's source code.

Let's start this particular journey by considering the problem of a typical operating system that supports disparate filesystem formats. An operating system may use data residing on its native filesystem, a CD-ROM, or a USB stick. These storage devices may, in turn, employ different filesystem organizations: NTFS or ext3fs for a Windows or Linux native filesystem, ISO-9660 for the CD-ROM, and, often, the legacy FAT-32 filesystem for the USB stick. Each filesystem uses different data structures for managing free space, for storing file metadata, and for organizing files into directories. Therefore, each filesystem requires different code for each operation on a file (open, read, write, seek, close, delete, and so on).

17.1. From Code to Pointers

I grew up in an era where different computers more often than not had incompatible filesystems, forcing me to transfer data from one machine to another over serial links. Therefore, the ability to read on my PC a flash card written on my camera never ceases to amaze me. Let's consider how the operating system would structure the code for accessing the different filesystems. One approach would be to employ a switch statement for each operation. Consider as an example a hypothetical implementation of the read system call under the FreeBSD operating system. Its kernel-side interface would look as follows:

int VOP_READ(

struct vnode *vp, /* File to read from */

struct uio *uio, /* Buffer specification */

int ioflag, /* I/O-specific flags */

struct ucred *cred) /* User's credentials */

{

/* Hypothetical implementation */

switch (vp->filesystem) {

case FS_NTFS: /* NTFS-specific code */

case FS_ISO9660: /* ISO-9660-specific code */

case FS_FAT32: /* FAT-32-specific code */

/* [...] */

}

}

This approach would bundle together code for the various filesystems, limiting modularity. Worse, adding support for a new filesystem type would require modifying the code of each system call implementation and recompiling the kernel. Moreover, adding a processing step to all the operations of a filesystem (for example, the mapping of remote user credentials) would also require the error-prone modification of each operation with the same boilerplate code.

As you might have guessed, our task at hand calls for some additional levels of indirection. Consider how the FreeBSD

Return Main Page Previous Page Next Page

®Online Book Reader