[ CCed to Stephen C. Tweedie, ext2/ext3 maintainer
because this looks like a real ext2/ext3 bug.
Tested against the 2.4.20 code.
- Cameron
]
On 12:34 08 Feb 2003, Ben Escoto <bescoto@stanford.edu> wrote:
| Can someone explain to me what is happening here:
|
| ~ $ touch foo
| ~ $ ln foo bar
| ~ $ ls foo bar
| bar foo
| ~ $ mv foo bar
| ~ $ ls foo bar
| bar foo
|
| I try to move a file over a hard linked copy of itself and the move
| fails, but there is no error. Is this the intended behavior?
It does seem a bit busted.
The same thing happens for me when I try this:
[~/zzzz]amadeus*> touch foo
[~/zzzz]amadeus*> ln foo bar
+ exec ln foo bar
[~/zzzz]amadeus*> ls -ld foo bar
-rw-rw---- 2 cameron cameron 0 Feb 9 10:35 bar
-rw-rw---- 2 cameron cameron 0 Feb 9 10:35 foo
[~/zzzz]amadeus*> /bin/mv foo bar
[~/zzzz]amadeus*> ls -ld foo bar
-rw-rw---- 2 cameron cameron 0 Feb 9 10:35 bar
-rw-rw---- 2 cameron cameron 0 Feb 9 10:35 foo
[~/zzzz]amadeus*> strace /bin/mv foo bar
execve("/bin/mv", ["/bin/mv", "foo",
"bar"], [/* 262 vars */]) = 0
uname({sys="Linux", node="amadeus.home", ...}) = 0
brk(0) = 0x8053aa4
old_mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) =
0x40016000
open("/etc/ld.so.preload", O_RDONLY) = -1 ENOENT (No such file or
directory)
open("/lib/i686/mmx/libc.so.6", O_RDONLY) = -1 ENOENT (No such file
or directory)
stat64("/lib/i686/mmx", 0xbfffc7ec) = -1 ENOENT (No such file or
directory)
open("/lib/i686/libc.so.6", O_RDONLY) = -1 ENOENT (No such file or
directory)
stat64("/lib/i686", 0xbfffc7ec) = -1 ENOENT (No such file or
directory)
open("/lib/mmx/libc.so.6", O_RDONLY) = -1 ENOENT (No such file or
directory)
stat64("/lib/mmx", 0xbfffc7ec) = -1 ENOENT (No such file or
directory)
open("/lib/libc.so.6", O_RDONLY) = 3
read(3, "\177ELF\1\1\1\0\0\0\0\0\0\0\0\0\3\0\3\0\1\0\0\0\0\304\1"...,
1024) = 1024
fstat64(3, {st_mode=S_IFREG|0755, st_size=5734740, ...}) = 0
old_mmap(NULL, 1267080, PROT_READ|PROT_EXEC, MAP_PRIVATE, 3, 0) = 0x40017000
mprotect(0x40143000, 38280, PROT_NONE) = 0
old_mmap(0x40143000, 24576, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED, 3,
0x12b000) = 0x40143000
old_mmap(0x40149000, 13704, PROT_READ|PROT_WRITE,
MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0) = 0x40149000
close(3) = 0
brk(0) = 0x8053aa4
brk(0x8053acc) = 0x8053acc
brk(0x8054000) = 0x8054000
geteuid32() = 331
umask(0) = 07
stat64("bar", {st_mode=S_IFREG|0660, st_size=0, ...}) = 0
brk(0x8055000) = 0x8055000
lstat64("foo", {st_mode=S_IFREG|0660, st_size=0, ...}) = 0
lstat64("bar", {st_mode=S_IFREG|0660, st_size=0, ...}) = 0
stat64(".", {st_mode=S_IFDIR|0770, st_size=4096, ...}) = 0
stat64(".", {st_mode=S_IFDIR|0770, st_size=4096, ...}) = 0
rename("foo", "bar") = 0
_exit(0) = ?
[~/zzzz]amadeus*>
So clearly this bug is at the OS level, since the rename() call is called,
does return success, and does achieve nothing!
Same results on ext2 as ext3.
A fsck after doing this on an ext2 doesn't see anything wrong and the
link counts seem still ok.
A quick glance at the ext2 and ext3 code doesn't enlighten me - it _looks_
ok, and doesn't have any stupid special cases for the src and dest of the
rename call being the same inode.
Stephen, can you see the problem?
--
Cameron Simpson, DoD#743 cs@zip.com.au http://www.zip.com.au/~cs/
I had a *bad* day. I had to subvert my principles and kowtow to an idiot.
Television makes these daily sacrifices possible. It deadens the inner core
of my being. - Martin Donovan, _Trust_