2007-03-23 17:33:51

by Timo Sirainen

[permalink] [raw]
Subject: 2.6.20 ext3 rename() returns success but doesn't unlink the source

The problem happened when I was stress testing my IMAP server using a
ext3 filesystem created inside 1GB file in XFS.

The ext3 image can be downloaded from
http://dovecot.org/tmp/broken-ext3fs.gz

Then do:

rename("/mnt/Maildir/.Trash/new/1174635781.P25986Q0M341350.hurina",
"/mnt/Maildir/.Trash/cur/1174635781.P25986Q0M341350.hurina:2,");

You'll see that the source file won't get unlinked from new/ directory,
even though rename() returns 0. (Don't use /bin/mv for testing, it'll
unlink(), not rename()).

This is fully reproduceable with me. Vanilla 2.6.20 kernel, x86-64 SMP.

Other renames that are broken:

/mnt/Maildir/.Trash/cur/1174634032.P23859Q0M8966.hurina:2,FR -> /mnt/Maildir/.Trash/cur/1174634032.P23859Q0M8966.hurina:2,RSe
/mnt/Maildir/.Trash/cur/1174655534.P24036Q0M568306.hurina:2, -> /mnt/Maildir/.Trash/cur/1174655534.P24036Q0M568306.hurina:2,FRde
/mnt/Maildir/.Trash/cur/1174634141.P26381Q0M456574.hurina:2,DRce -> /mnt/Maildir/.Trash/cur/1174634141.P26381Q0M456574.hurina:2,DFRce
/mnt/Maildir/.Trash/cur/1174634674.P4936Q0M158888.hurina:2,b -> /mnt/Maildir/.Trash/cur/1174634674.P4936Q0M158888.hurina:2,Dae
/mnt/Maildir/.Trash/cur/1174635529.P21439Q0M369287.hurina:2,FRabd -> /mnt/Maildir/.Trash/cur/1174635529.P21439Q0M369287.hurina:2,Sab
/mnt/Maildir/.Trash/cur/1174633952.P22125Q1M462390.hurina:2,Sbc -> /mnt/Maildir/.Trash/cur/1174633952.P22125Q1M462390.hurina:2,DFRSbc
/mnt/Maildir/.Trash/cur/1174635536.P21699Q0M303872.hurina:2,FRSde -> /mnt/Maildir/.Trash/cur/1174635536.P21699Q0M303872.hurina:2,Sab
/mnt/Maildir/.Trash/cur/1174634168.P26948Q0M641713.hurina:2,bdc -> /mnt/Maildir/.Trash/cur/1174634168.P26948Q0M641713.hurina:2,Rbdc
/mnt/Maildir/.Trash/cur/1174635988.P29139Q0M957075.hurina:2,DRd -> /mnt/Maildir/.Trash/cur/1174635988.P29139Q0M957075.hurina:2,be
/mnt/Maildir/.Trash/cur/1174635746.P25391Q0M231431.hurina:2, -> /mnt/Maildir/.Trash/cur/1174635746.P25391Q0M231431.hurina:2,abe
/mnt/Maildir/.Trash/cur/1174634129.P26063Q0M629252.hurina:2,DRde -> /mnt/Maildir/.Trash/cur/1174634129.P26063Q0M629252.hurina:2,DRd
/mnt/Maildir/.Trash/cur/1174635744.P25345Q0M695919.hurina:2,c -> /mnt/Maildir/.Trash/cur/1174635744.P25345Q0M695919.hurina:2,abc
/mnt/Maildir/.Trash/cur/1174634548.P2478Q0M911503.hurina:2,DFSad -> /mnt/Maildir/.Trash/cur/1174634548.P2478Q0M911503.hurina:2,DSa
/mnt/Maildir/.Trash/cur/1174635164.P14762Q0M158308.hurina:2, -> /mnt/Maildir/.Trash/cur/1174635164.P14762Q0M158308.hurina
/mnt/Maildir/.Trash/cur/1174634671.P4940Q0M644537.hurina:2,Re -> /mnt/Maildir/.Trash/cur/1174634671.P4940Q0M644537.hurina:2,bd
/mnt/Maildir/.Trash/cur/1174634633.P3937Q0M292724.hurina:2,FRSd -> /mnt/Maildir/.Trash/cur/1174634633.P3937Q0M292724.hurina:2,FRSabdce
/mnt/Maildir/.Trash/cur/1174633952.P22146Q0M723956.hurina:2,Rbde -> /mnt/Maildir/.Trash/cur/1174633952.P22146Q0M723956.hurina:2,Sbde
/mnt/Maildir/.Trash/cur/1174635616.P23078Q4.hurina:2,DFR -> /mnt/Maildir/.Trash/cur/1174635616.P23078Q4.hurina:2,Rb


Attachments:
signature.asc (189.00 B)
This is a digitally signed message part

2007-03-23 23:18:35

by Timo Sirainen

[permalink] [raw]
Subject: Re: 2.6.20 ext3 rename() returns success but doesn't unlink the source

On Fri, 2007-03-23 at 23:24 +0100, Guillaume Chazarain wrote:
> Timo Sirainen a ?crit :
>
> > rename("/mnt/Maildir/.Trash/new/1174635781.P25986Q0M341350.hurina",
> > "/mnt/Maildir/.Trash/cur/1174635781.P25986Q0M341350.hurina:2,");
>
> $ ls -li /mnt/Maildir/.Trash/new/1174635781.P25986Q0M341350.hurina /mnt/Maildir/.Trash/cur/1174635781.P25986Q0M341350.hurina:2,
> 122481 -rw------- 2 1000 1000 3091 Mar 23 08:43 /mnt/Maildir/.Trash/cur/1174635781.P25986Q0M341350.hurina:2,
> 122481 -rw------- 2 1000 1000 3091 Mar 23 08:43 /mnt/Maildir/.Trash/new/1174635781.P25986Q0M341350.hurina
>
> All your files in the list are hard linked.
> http://git.kernel.org/?p=linux/kernel/git/torvalds/linux-2.6.git;a=blob;f=fs/namei.c;h=ee60cc4d3453209723d6f70982e7083d7cb39477;hb=HEAD#l2447
> seems to handle your case as you see it:
> if (old_dentry->d_inode == new_dentry->d_inode)
> return 0;

Hmm. Oh. So this is this intentional? First I ever heard of it, and also
goes against my logic. I'll go complain to man pages people then. This
will make my error handling difficult..


Attachments:
signature.asc (189.00 B)
This is a digitally signed message part

2007-03-23 23:45:18

by Andreas Dilger

[permalink] [raw]
Subject: Re: 2.6.20 ext3 rename() returns success but doesn't unlink the source

On Mar 24, 2007 01:18 +0200, Timo Sirainen wrote:
> On Fri, 2007-03-23 at 23:24 +0100, Guillaume Chazarain wrote:
> > Timo Sirainen a ?crit :
> >
> > > rename("/mnt/Maildir/.Trash/new/1174635781.P25986Q0M341350.hurina",
> > > "/mnt/Maildir/.Trash/cur/1174635781.P25986Q0M341350.hurina:2,");
> >
> > $ ls -li /mnt/Maildir/.Trash/new/1174635781.P25986Q0M341350.hurina /mnt/Maildir/.Trash/cur/1174635781.P25986Q0M341350.hurina:2,
> > 122481 -rw------- 2 1000 1000 3091 Mar 23 08:43 /mnt/Maildir/.Trash/cur/1174635781.P25986Q0M341350.hurina:2,
> > 122481 -rw------- 2 1000 1000 3091 Mar 23 08:43 /mnt/Maildir/.Trash/new/1174635781.P25986Q0M341350.hurina
> >
> > All your files in the list are hard linked.
> > http://git.kernel.org/?p=linux/kernel/git/torvalds/linux-2.6.git;a=blob;f=fs/namei.c;h=ee60cc4d3453209723d6f70982e7083d7cb39477;hb=HEAD#l2447
> > seems to handle your case as you see it:
> > if (old_dentry->d_inode == new_dentry->d_inode)
> > return 0;
>
> Hmm. Oh. So this is this intentional? First I ever heard of it, and also
> goes against my logic. I'll go complain to man pages people then. This
> will make my error handling difficult..

Yes, it is a very counter-intuitive requirement in the POSIX spec. The
GNU user tools do what is expected (unlink the source file).

Cheers, Andreas
--
Andreas Dilger
Principal Software Engineer
Cluster File Systems, Inc.

2007-03-23 23:52:47

by Guillaume Chazarain

[permalink] [raw]
Subject: Re: 2.6.20 ext3 rename() returns success but doesn't unlink the source

Timo Sirainen a ?crit :

> rename("/mnt/Maildir/.Trash/new/1174635781.P25986Q0M341350.hurina",
> "/mnt/Maildir/.Trash/cur/1174635781.P25986Q0M341350.hurina:2,");

$ ls -li /mnt/Maildir/.Trash/new/1174635781.P25986Q0M341350.hurina /mnt/Maildir/.Trash/cur/1174635781.P25986Q0M341350.hurina:2,
122481 -rw------- 2 1000 1000 3091 Mar 23 08:43 /mnt/Maildir/.Trash/cur/1174635781.P25986Q0M341350.hurina:2,
122481 -rw------- 2 1000 1000 3091 Mar 23 08:43 /mnt/Maildir/.Trash/new/1174635781.P25986Q0M341350.hurina

All your files in the list are hard linked.
http://git.kernel.org/?p=linux/kernel/git/torvalds/linux-2.6.git;a=blob;f=fs/namei.c;h=ee60cc4d3453209723d6f70982e7083d7cb39477;hb=HEAD#l2447
seems to handle your case as you see it:
if (old_dentry->d_inode == new_dentry->d_inode)
return 0;

Regards.

--
Guillaume