Text File

Apur-ee.178 net.bugs.2bsd,net.bugs.v7 utzoo!decvax!pur-ee!bruner Fri Dec 11 21:22:35 1981 "holes" in directories We discovered a particularly nasty problem with the way that UNIX handles directories when cleaning up a bad system crash. A "hole" (region where no blocks are allocated) was created in /usr/tmp. "fsck" reported no unusual errors, but when we attempted to touch the inside of this directory (e.g. with "ls") we had all sorts of errors from our disc driver.

The problem is that UNIX assumes there will never be holes in directories (since normal operation does not create them). The routine "namei" which searches directories contains the line:

bp = bread(dp->i_dev, bmap(dp, (daddr_t)(u.u_offset>>BSHIFT), B_READ));

If "bmap" is called with B_READ it will not allocate blocks to fill in "holes"; rather, it returns -1 if a hole exists. This is then passed directly to "bread". If your disc driver doesn't check for negative block numbers (ours didn't), you'll get invalid cylinder/surface/sector errors from your disc. Even if the disc driver does catch the error, you still have problems. In 2.8bsd and 4.1bsd the blocks following the "hole" are never reached, so you could lose a lot of files if the hole occurred near the beginning of the directory. If there is no check for an error from "bread" then all sorts of inconsistent things can happen.

This problem exists in V7, 2.8bsd, and 4.1bsd. It is difficult for "fsck" to fill in the hole, but certainly it should complain about the problem. I implemented a kernel fix -- just have "namei" check the result of "bmap"; if negative (and the filesystem is read-write) it then fills in the hole, otherwise, the "hole" is skipped so that it can't cause any harm. The fix varies slightly from system to system, but is approximately:

#include "../h/filsys.h" .... daddr_t bn; struct filsys *getfs(); .... if ((bn=bmap(dp, (daddr_t)(u.u_offset>>BSHIFT), B_READ) i_dev), minor(dp->i_dev), dp->i_number); if (getfs(dp->i_dev)->s_ronly || (bn=bmap(dp, (daddr_t)(u.u_offset>>BSHIFT), B_WRITE)) i_dev, bn);

V6 does not have this problem, since it always fills in "holes" when the file is read (no 3rd argument to "bmap").

--John Bruner

----------------------------------------------------------------- gopher://quux.org/ conversion by John Goerzen <jgoerzen@complete.org> of http://communication.ucsd.edu/A-News/

This Usenet Oldnews Archive article may be copied and distributed freely, provided:

1. There is no money collected for the text(s) of the articles.

2. The following notice remains appended to each copy:

The Usenet Oldnews Archive: Compilation Copyright (C) 1981, 1996 Bruce Jones, Henry Spencer, David Wiseman.