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.