Search code examples
posixrenameext3

file rename on ext3 appears to break POSIX spec


I am struggling to understand what is going on in a test I am running. Test is two shell scripts running on the same machine.

A:

    #!/bin/bash
    touch target;
    for ((i=0; i < 1000; i=i+1)); do
        echo "snafu$i" > $1/file$i;
        mv -f $1/file$i $1/target; 
    done; 

B:

    #!/bin/bash
    while(true);do 
        cat $1/target; 
    done

So I run A /ext3_dir, then run B /ext3_dir > out (so only errors go to std out).

This all works fine and as expected according to the POSIX spec for 'rename':

If the link named by the new argument exists, it shall be removed and old renamed to new. In this case, a link named new shall remain visible to other processes throughout the renaming operation and refer either to the file referred to by new or old before the operation began.

However if I add a hard-link to the temporary file before doing the move:

    #!/bin/bash
    touch target;
    for ((i=0; i < 1000; i=i+1)); do
        echo "snafu$i" > $1/file$i;
        ln $1/file$i $1/link$i
        mv -f $1/file$i $1/target; 
    done; 

I get "No such file or directory" errors on the reading side - seemingly in contravention of the POSIX spec.

Can anyone shed any light on this behaviour? Is the test valid? I can't figure out why creating an extra link to the file I'm moving should impact the ability to read from the move destination.


Solution

  • It turns out this was a known problem on some redhat versions:

    https://bugzilla.redhat.com/show_bug.cgi?id=438076