Bug 138849 - unlink() misbehaviour/interaction with readdir()
unlink() misbehaviour/interaction with readdir()
Product: Fedora
Classification: Fedora
Component: glibc (Show other bugs)
i686 Linux
medium Severity medium
: ---
: ---
Assigned To: Jakub Jelinek
Brian Brock
Depends On:
  Show dependency treegraph
Reported: 2004-11-11 11:39 EST by Jonathan Allen
Modified: 2007-11-30 17:10 EST (History)
2 users (show)

See Also:
Fixed In Version:
Doc Type: Bug Fix
Doc Text:
Story Points: ---
Clone Of:
Last Closed: 2004-11-12 14:31:04 EST
Type: ---
Regression: ---
Mount Type: ---
Documentation: ---
Verified Versions:
Category: ---
oVirt Team: ---
RHEL 7.3 requirements from Atomic Host:
Cloudforms Team: ---

Attachments (Terms of Use)
Test program to demonstrate bug (1.27 KB, text/plain)
2004-11-11 11:43 EST, Jonathan Allen
no flags Details

  None (edit)
Description Jonathan Allen 2004-11-11 11:39:46 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):

How reproducible:

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
 5505650: .file
 5505651: file
 5410128: ..
 5505649: .

Expected Results:  Dir = D16775
 5505650: .file
       0: file
 5410128: ..
 5505649: .

Additional info:
Comment 1 Jonathan Allen 2004-11-11 11:43:46 EST
Created attachment 106508 [details]
Test program to demonstrate bug

Compile simply as:

   cc z1.c

then run as:

Comment 2 Jakub Jelinek 2004-11-11 15:08:25 EST
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.
Comment 3 Jonathan Allen 2004-11-12 07:26:55 EST
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.
Comment 4 Ulrich Drepper 2004-11-12 14:31:04 EST
If your program expects this behavior, fix it.  The glibc code is
correct and there will be no change.

Note You need to log in before you can comment on or make changes to this bug.