[<prev] [next>] [thread-next>] [day] [month] [year] [list]
Message-ID: <7bbc9419-5c56-450a-b5a0-efeae7457113@gmail.com>
Date: Thu, 27 Nov 2025 16:53:43 +0300
From: Vyacheslav Kovalevsky <slava.kovalevskiy.2014@...il.com>
To: clm@...com, dsterba@...e.com
Cc: linux-btrfs@...r.kernel.org, linux-kernel@...r.kernel.org
Subject: File system corruption after renaming directory and creating a new
file with same name if system crashes
File system becomes corrupted after renaming directory, creating and
syncing a new file with the same name if system crashes.
Detailed description
====================
Hello, we have found another issue with btrfs crash behavior.
In short, two directories are created and synced. Then, first directory
is renamed as subdirectory of the second directory. A new file is
created with name that was previously associated with the first
directory. The file is fsync'ed and moved under the renamed directory
and fsync'ed again. After a crash, file system cannot be mounted,
reporting block corruption.
It seems that the directory entry becomes corrupted when the `nlink`
value is erroneously set to 2, somehow.
System info
===========
Linux version 6.18.0-rc7, also tested on 6.18.0-rc2 and 6.14.11.
How to reproduce
================
Test:
```
#include <errno.h>
#include <fcntl.h>
#include <stdio.h>
#include <string.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>
int main() {
int status;
int file_fd;
status = mkdir("dir1", S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH);
printf("MKDIR: %d\n", status);
status = mkdir("dir2", S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH);
printf("MKDIR: %d\n", status);
sync();
status = rename("dir1", "dir2/dir3");
printf("RENAME: %d\n", status);
// create regular file with the name directory had before rename
status = open("dir1", O_RDWR | O_CREAT);
printf("OPEN: %d\n", status);
file_fd = status;
status = fsync(file_fd);
printf("FSYNC: %d\n", status);
status = rename("dir1", "dir2/dir3/not-dir");
printf("RENAME: %d\n", status);
status = fsync(file_fd);
printf("FSYNC: %d\n", status);
}
```
dmesg:
```
[ 17.559361] BTRFS: device fsid 17a75b88-e58e-457d-83db-ea6599920bc7
devid 1 transid 9 /dev/vdb (253:16) scanned by mount (1095)
[ 17.559676] BTRFS info (device vdb): first mount of filesystem
17a75b88-e58e-457d-83db-ea6599920bc7
[ 17.559690] BTRFS info (device vdb): using crc32c (crc32c-lib) checksum
algorithm
[ 17.562785] BTRFS info (device vdb): start tree-log replay
[ 17.563301] page: refcount:2 mapcount:0 mapping:0000000077ae2817
index:0x1d00 pfn:0x1057ac
[ 17.563305] memcg:ffff89a500340000
[ 17.563307] aops:btree_aops ino:1
[ 17.563311] flags:
0x17ffffc800402a(uptodate|lru|private|writeback|node=0|zone=2|lastcpupid=0x1fffff)
[ 17.563315] raw: 0017ffffc800402a fffff9aa84135708 fffff9aa84073d88
ffff89a51cb23a90
[ 17.563318] raw: 0000000000001d00 ffff89a502951b40 00000002ffffffff
ffff89a500340000
[ 17.563319] page dumped because: eb page dump
[ 17.563320] BTRFS critical (device vdb): corrupt leaf: root=5
block=30408704 slot=6 ino=257, invalid nlink: has 2 expect no more than
1 for dir
[ 17.564768] BTRFS info (device vdb): leaf 30408704 gen 10 total ptrs 17
free space 14869 owner 5
[ 17.564772] item 0 key (256 INODE_ITEM 0) itemoff 16123 itemsize 160
[ 17.564775] inode generation 3 transid 9 size 16 nbytes 16384
[ 17.564776] block group 0 mode 40755 links 1 uid 0 gid 0
[ 17.564778] rdev 0 sequence 2 flags 0x0
[ 17.564779] atime 1764249615.0
[ 17.564781] ctime 1764249645.130028300
[ 17.564782] mtime 1764249645.130028300
[ 17.564784] otime 1764249615.0
[ 17.564785] item 1 key (256 INODE_REF 256) itemoff 16111 itemsize 12
[ 17.564787] index 0 name_len 2
[ 17.564789] item 2 key (256 DIR_ITEM 2363071922) itemoff 16077 itemsize 34
[ 17.564791] location key (257 1 0) type 2
[ 17.564792] transid 9 data_len 0 name_len 4
[ 17.564794] item 3 key (256 DIR_ITEM 2676584006) itemoff 16043 itemsize 34
[ 17.564795] location key (258 1 0) type 2
[ 17.564797] transid 9 data_len 0 name_len 4
[ 17.564798] item 4 key (256 DIR_INDEX 2) itemoff 16009 itemsize 34
[ 17.564800] location key (257 1 0) type 2
[ 17.564801] transid 9 data_len 0 name_len 4
[ 17.564803] item 5 key (256 DIR_INDEX 3) itemoff 15975 itemsize 34
[ 17.564805] location key (258 1 0) type 2
[ 17.564806] transid 9 data_len 0 name_len 4
[ 17.564807] item 6 key (257 INODE_ITEM 0) itemoff 15815 itemsize 160
[ 17.564809] inode generation 9 transid 10 size 14 nbytes 0
[ 17.564811] block group 0 mode 40755 links 2 uid 0 gid 0
[ 17.564812] rdev 0 sequence 1 flags 0x0
[ 17.564813] atime 1764249645.130028300
[ 17.564815] ctime 1764249645.130028300
[ 17.564816] mtime 1764249645.130028300
[ 17.564818] otime 1764249645.130028300
[ 17.564819] item 7 key (257 INODE_REF 256) itemoff 15801 itemsize 14
[ 17.564821] index 2 name_len 4
[ 17.564822] item 8 key (257 INODE_REF 258) itemoff 15787 itemsize 14
[ 17.564824] index 2 name_len 4
[ 17.564825] item 9 key (257 DIR_ITEM 3753155587) itemoff 15750 itemsize 37
[ 17.564827] location key (259 1 0) type 1
[ 17.564828] transid 10 data_len 0 name_len 7
[ 17.564830] item 10 key (257 DIR_INDEX 2) itemoff 15713 itemsize 37
[ 17.564831] location key (259 1 0) type 1
[ 17.564833] transid 10 data_len 0 name_len 7
[ 17.564834] item 11 key (258 INODE_ITEM 0) itemoff 15553 itemsize 160
[ 17.564836] inode generation 9 transid 10 size 8 nbytes 0
[ 17.564837] block group 0 mode 40755 links 1 uid 0 gid 0
[ 17.564839] rdev 0 sequence 1 flags 0x0
[ 17.564840] atime 1764249645.130028300
[ 17.564842] ctime 1764249645.130028300
[ 17.564843] mtime 1764249645.130028300
[ 17.564844] otime 1764249645.130028300
[ 17.564846] item 12 key (258 INODE_REF 256) itemoff 15539 itemsize 14
[ 17.564847] index 3 name_len 4
[ 17.564849] item 13 key (258 DIR_ITEM 1843588421) itemoff 15505 itemsize 34
[ 17.564851] location key (257 1 0) type 2
[ 17.564852] transid 10 data_len 0 name_len 4
[ 17.564853] item 14 key (258 DIR_INDEX 2) itemoff 15471 itemsize 34
[ 17.564855] location key (257 1 0) type 2
[ 17.564856] transid 10 data_len 0 name_len 4
[ 17.564858] item 15 key (259 INODE_ITEM 0) itemoff 15311 itemsize 160
[ 17.564860] inode generation 10 transid 10 size 0 nbytes 0
[ 17.564861] block group 0 mode 100000 links 1 uid 0 gid 0
[ 17.564863] rdev 0 sequence 2 flags 0x0
[ 17.564864] atime 1764249645.139028211
[ 17.564865] ctime 1764249645.140028202
[ 17.564867] mtime 1764249645.139028211
[ 17.564868] otime 1764249645.139028211
[ 17.564869] item 16 key (259 INODE_REF 257) itemoff 15294 itemsize 17
[ 17.564870] index 2 name_len 7
[ 17.564872] BTRFS error (device vdb): block=30408704 write time tree
block corruption detected
[ 17.566147] BTRFS: error (device vdb) in btrfs_commit_transaction:2535:
errno=-5 IO failure (Error while writing out transaction)
[ 17.567374] BTRFS warning (device vdb state E): Skipping commit of
aborted transaction.
[ 17.567377] BTRFS error (device vdb state EA): Transaction aborted
(error -5)
[ 17.568502] BTRFS: error (device vdb state EA) in
cleanup_transaction:2020: errno=-5 IO failure
[ 17.569956] BTRFS: error (device vdb state EA) in
btrfs_replay_log:2093: errno=-5 IO failure (Failed to recover log tree)
[ 17.571778] BTRFS error (device vdb state EA): open_ctree failed: -5
```
Steps:
1. Create and mount new btrfs file system in default configuration.
2. Change directory to root of the file system and run the compiled test.
3. Cause hard system crash (e.g. QEMU `system_reset` command).
4. Remount file system after crash.
5. Observe that mount fails.
Notes:
- if path in open() is changed to any other name (instead of `dir1`) the
bug will not manifest.
Powered by blists - more mailing lists