From: Vyacheslav Kovalevsky <slava.kovalevskiy.2014@gmail.com>
To: clm@fb.com, dsterba@suse.com
Cc: linux-btrfs@vger.kernel.org, linux-kernel@vger.kernel.org
Subject: Symlink entry is not persisted after rename if system crashes
Date: Thu, 23 Oct 2025 18:34:18 +0300 [thread overview]
Message-ID: <ac949c74-90c2-4b9a-b7fd-1ffc5c3175c7@gmail.com> (raw)
Under some circumstances, new directory entry of a symbolic link is not
persisted after rename if the file system crashes.
Detailed description
====================
Hello, we are doing research on testing file system crash consistency.
During
testing we found this issue with btrfs file system. In short, a symbolic
link
is created and renamed. Directory entries are synced using `fsync` after
every
step. However, after a crash, the symbolic link new directory entry is not
persisted (symbolic link has the old name). Read the test below for more
details.
System info
===========
Linux version 6.18.0-rc2 (root@ubuntu) (gcc (Ubuntu 15.2.0-4ubuntu4)
15.2.0,
GNU ld (GNU Binutils for Ubuntu) 2.45) #2 SMP PREEMPT_DYNAMIC Thu Oct 23
12:32:29 UTC 2025
Also tested on Linux 6.14.11.
Operating System: Ubuntu 25.10
CPU architecture: x86_64
btrfs-progs version: v6.16
-EXPERIMENTAL -INJECT -STATIC +LZO +ZSTD +UDEV +FSVERITY +ZONED
CRYPTO=builtin
Tested on QEMU emulator version 10.1.1.
How to reproduce
================
```
#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 root_fd;
int dir_fd1;
int dir_fd2;
status = mkdir("dir", S_IRWXO);
printf("MKDIR: %d\n", status);
status = open(".", O_RDONLY | O_DIRECTORY);
printf("OPEN: %d\n", status);
root_fd = status;
// persist `dir`
status = fsync(root_fd);
printf("FSYNC: %d\n", status);
status = symlink("foobar", "dir/slink-old");
printf("SYMLINK: %d\n", status);
status = open("dir", O_RDONLY | O_DIRECTORY);
printf("OPEN: %d\n", status);
dir_fd1 = status;
// persist `slink-old`
status = fsync(dir_fd1);
printf("FSYNC: %d\n", status);
status = rename("dir/slink-old", "dir/slink-new");
printf("RENAME: %d\n", status);
status = open("dir", O_RDONLY | O_DIRECTORY);
printf("OPEN: %d\n", status);
dir_fd2 = status;
// persist `slink-new`
status = fsync(dir_fd2);
printf("FSYNC: %d\n", status);
}
```
Short test summary:
1. Directory `dir` is created.
2. Directory `.` is fsynced (`dir` entry should persist).
3. New symbolic link `slink-old` is created in `dir`.
4. Directory `dir` is fsynced using descriptor 1 (`slink-old` entry should
persist).
5. Link is renamed from `slink-old` to `slink-new`.
6. Directory `dir` is fsynced using decriptor 2 (`slink-new` entry should
persist).
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 `dir` directory contains entry named `slink-old` instead of
`slink-new`.
Notes:
- In other file systems (ext4, xfs, nilfs2) the `dir` will contain new
(`slink-new`) entry, not the old one.
- The problem only affects symlinks, but not regular files.
- The problem only arises if `dir` fsyncs are made using different
descriptors.
next reply other threads:[~2025-10-23 15:34 UTC|newest]
Thread overview: 2+ messages / expand[flat|nested] mbox.gz Atom feed top
2025-10-23 15:34 Vyacheslav Kovalevsky [this message]
2025-10-24 11:59 ` Symlink entry is not persisted after rename if system crashes Filipe Manana
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=ac949c74-90c2-4b9a-b7fd-1ffc5c3175c7@gmail.com \
--to=slava.kovalevskiy.2014@gmail.com \
--cc=clm@fb.com \
--cc=dsterba@suse.com \
--cc=linux-btrfs@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox