On Wed, Feb 13, 2019 at 12:14:03PM +0000, fdman...@kernel.org wrote:
> From: Filipe Manana <fdman...@suse.com>
> 
> After a succession of rename operations of different files and fsyncing
> one of them, such that each file gets a new name that corresponds to an
> old name of another file, we can end up with a log that will cause a
> failure when attempted to replay at mount time (an EEXIST error).
> We currently have correct behaviour when such succession of renames
> involves only two files, but if there are more files involved, we end up
> not logging all the inodes that are needed, therefore resulting in a
> failure when attempting to replay the log.
> 
> Example:
> 
>   $ mkfs.btrfs -f /dev/sdb
>   $ mount /dev/sdb /mnt
> 
>   $ mkdir /mnt/testdir
>   $ touch /mnt/testdir/fname1
>   $ touch /mnt/testdir/fname2
> 
>   $ sync
> 
>   $ mv /mnt/testdir/fname1 /mnt/testdir/fname3
>   $ mv /mnt/testdir/fname2 /mnt/testdir/fname4
>   $ ln /mnt/testdir/fname3 /mnt/testdir/fname2
> 
>   $ touch /mnt/testdir/fname1
>   $ xfs_io -c "fsync" /mnt/testdir/fname1
> 
>   <power failure>
> 
>   $ mount /dev/sdb /mnt
>   mount: mount /dev/sdb on /mnt failed: File exists
> 
> So fix this by checking all inode dependencies when logging an inode. That
> is, if one logged inode A has a new name that matches the old name of some
> other inode B, check if inode B has a new name that matches the old name
> of some other inode C, and so on. This fix is implemented not by doing any
> recursive function calls but by using an iterative method using a linked
> list that is used in a first-in-first-out fashion.
> 
> A test case for fstests follows soon.
> 
> Signed-off-by: Filipe Manana <fdman...@suse.com>

1 and 2 lightly reviewed, added to for-next and scheduled for 5.1.
Thanks.

Reply via email to