Red Hat Bugzilla – Bug 138849
unlink() misbehaviour/interaction with readdir()
Last modified: 2007-11-30 17:10:54 EST
From Bugzilla Helper:
User-Agent: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.7.3)
Description of problem:
unlink() doesn't seem to synchronise with readdir() while the
directory holding the file is open.
Test program (supplied as attachment) creates a directory, then two
files. It then opens the directory and reads the entries, printing
the inode number and the filename. When it finds the first entry, it
deletes the second file and immediately tries to fopen() it - as I
expected, the fopen() call fails [as it should]. However, the next
call to readdir() which is the deleted file, shows it with a non-zero
inode number as if the file still exists.
Version-Release number of selected component (if applicable):
Steps to Reproduce:
1. compile test program
2. run test program
3. observe output
4. do 'ls -al' on the created directory
Actual Results: Dir = D16775
Expected Results: Dir = D16775
Created attachment 106508 [details]
Test program to demonstrate bug
Compile simply as:
then run as:
Please cite which standard mandates the behaviour you are asking for.
To my knowledge POSIX doesn't require this and the current glibc behaviour
(caching directory entries). If you want to see the effect on the next readdir,
you need to closedir and opendir again.
The behaviour I expected has 'standard' behaviour for Unices since
version 5 (and I don't mean System V, either). This behaviour
destroys the ability to make a single clean pass through a directory
and not get (misleading) error reports for files that have been
removed as a part of processing others.
In this case, I read parameters and control information from an ASCII
file starting with a '.' character and use it to process images held
under their own (the same) filename without a preceding '.' as
generated by some graphics program. When processed, both files are
unlinked. This means that I then (later on in the pass) hit what
looks to be an error: a filename without a dot which doesn't have a
matching '.' file which speaks of another application program error.
It isn't that I want to see the effect on the next readdir(), it is
that the readdir() is returning old and invalid information which
needn't be because of the current program's activities. All programs
that process directories know to ignore entries with a zero inode
value as being a file that has been deleted but the directory slot
hasn't been re-used yet, but that a file with a non-zero inode value
is a good file. This behaviour breaks that long-standing assumption
and calls into question the integrity of the file-system by
presenting a program with what looks like a valid directory entry to
a file that doesn't exist.
If your program expects this behavior, fix it. The glibc code is
correct and there will be no change.