8

I got a copy of The Unix Programming Environment by Kernighan and Pike from a garage sale. I'm very interested in the chapter about the UNIX filesystem. Naturally, I also found this passage very interesting:

The time has come to look at the bytes in a directory:

$ od -cb .
0000000    4    ;    .   \0   \0   \0   \0   \0   \0   \0   \0   \0   \0   \0   \0   \0
          064  073  056  000  000  000  000  000  000  000  000  000  000  000  000  000
....

It was really long so I won't type the whole thing out. The gist of it was that it displayed the directory in the way it was stored on the system. I quickly rushed to my laptop (Debian) to try this out. I typed out the command as it was in the book.

$ od -cb .
od: .: read error: Is a directory
0000000

Obviously it won't let me view the raw contents of the directory. So here's my question.

Does the Linux kernel store directories in a different way that the original UNIX kernel did? If not, why is there the need to conceal the actual bytes of the directory from the user?

3 Answers 3

7

Each filesystem type stores directories in a different way. There are many different filesystem types with different characteristics — good for high throughput, good for high concurrency, good for limited-memory environments, different compromises between read and write performance, between complexity and stability, etc. Your book describes a filesystem used in early Unix systems. Modern systems support many different filesystems.

The very early versions of Unix had a lot of filesystem manipulation outside the kernel. For example, mkdir and rmdir worked by editing some filesystem data structures directly. This was quickly replaced by a uniform directory access interface, the opendir/readdir/closedir family, which allowed applications to manipulate directories without having to know how they were implemented under the hood.

The reason you can't read directory contents under Linux isn't because they have to be concealed, but because features exist only if they are implemented, and this feature is pointless and has a cost. Given that the format depends on the filesystem, it's a rather pointless feature: a program can't know the format of what it's reading. It isn't a completely trivial feature to support either: some filesystems organize directories in ways that aren't just a stream of bytes, for example it may be organized as a B-tree. Some Unix variants still allow applications to read directory contents directly, for backward compatibility, but Linux doesn't have this feature (and never had as far as I can recall — it was already an obsolete feature in the early 1990s).

1
  • I wouldn't use the word "quickly" for a feature that took several years to become the accepted approach. Things that happened 30-odd years ago didn't happen more quickly just because it was a while ago. Feb 22, 2016 at 0:03
4

Yes, but:

  • modern systems store filenames differently. In original Unix, names were limited to 14 characters, with 2 bytes for inode.
  • the interface to the directory is via functions opendir, readdir, closedir rather than open, read, close to reflect the change in organization.
  • because no one has a practical need for reading 16-byte directory entries, the designers omitted the ability to read raw directory files from programs that are designed to read files.

Further reading:

0
3

Yes, the Linux kernel uses VFS to abstract different filesystems, and doesn't allow you to read(2) a directory.

But, if you are really interested in the raw contents of a directory in Linux EXT2/3/4 filesystem, you can use the debugfs(8) utility from e2fsprogs which will allowing you to read or dump directories as regular files.

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .