Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings
forked fromtorvalds/linux

Commit9a6509c

Browse files
fdmananakdave
authored andcommitted
Btrfs: fix log replay failure after linking special file and fsync
If in the same transaction we rename a special file (fifo, character/blockdevice or symbolic link), create a hard link for it having its old namethen sync the log, we will end up with a log that can not be replayed andat when attempting to replay it, an EEXIST error is returned and mountingthe filesystem fails. Example scenario: $ mkfs.btrfs -f /dev/sdc $ mount /dev/sdc /mnt $ mkdir /mnt/testdir $ mkfifo /mnt/testdir/foo # Make sure everything done so far is durably persisted. $ sync # Create some unrelated file and fsync it, this is just to create a log # tree. The file must be in the same directory as our special file. $ touch /mnt/testdir/f1 $ xfs_io -c "fsync" /mnt/testdir/f1 # Rename our special file and then create a hard link with its old name. $ mv /mnt/testdir/foo /mnt/testdir/bar $ ln /mnt/testdir/bar /mnt/testdir/foo # Create some other unrelated file and fsync it, this is just to persist # the log tree which was modified by the previous rename and link # operations. Alternatively we could have modified file f1 and fsync it. $ touch /mnt/f2 $ xfs_io -c "fsync" /mnt/f2 <power failure> $ mount /dev/sdc /mnt mount: mount /dev/sdc on /mnt failed: File existsThis happens because when both the log tree and the subvolume's tree havean entry in the directory "testdir" with the same name, that is, thereis one key (258 INODE_REF 257) in the subvolume tree and another one inthe log tree (where 258 is the inode number of our special file and 257is the inode for directory "testdir"). Only the data of those two keysdiffers, in the subvolume tree the index field for inode reference hasa value of 3 while the log tree it has a value of 5. Because the same keyexists in both trees, but have different index, the log replay fails withan -EEXIST error when attempting to replay the inode reference from thelog tree.Fix this by setting the last_unlink_trans field of the inode (our specialfile) to the current transaction id when a hard link is created, as thisforces logging the parent directory inode, solving the conflict at logreplay time.A new generic test case for fstests was also submitted.Signed-off-by: Filipe Manana <fdmanana@suse.com>Signed-off-by: David Sterba <dsterba@suse.com>
1 parentd4dfc0f commit9a6509c

File tree

1 file changed

+1
-1
lines changed

1 file changed

+1
-1
lines changed

‎fs/btrfs/tree-log.c‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5851,7 +5851,7 @@ int btrfs_log_new_name(struct btrfs_trans_handle *trans,
58515851
* this will force the logging code to walk the dentry chain
58525852
* up for the file
58535853
*/
5854-
if (S_ISREG(inode->vfs_inode.i_mode))
5854+
if (!S_ISDIR(inode->vfs_inode.i_mode))
58555855
inode->last_unlink_trans=trans->transid;
58565856

58575857
/*

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp