Re: File size is not persisted after opening the file with O_TRUNC flag and creating hard link if system crashes
From: Filipe Manana
Date: Tue Feb 17 2026 - 13:33:34 EST
On Tue, Feb 17, 2026 at 8:43 AM Vyacheslav Kovalevsky
<slava.kovalevskiy.2014@xxxxxxxxx> wrote:
>
> Detailed description
> ====================
>
> Hello, there seems to be an issue with btrfs crash behavior:
>
> 1. Create an empty file in a directory.
> 2. Fill file with data (e.g. truncate) and sync the file.
By the way, truncate doesn't fill any data, it just increases i_size
and leaves a hole in the file.
> 3. Open file with O_TRUNC flag (should set size to 0) and sync the file.
A truncate to 0 achieves the same, O_TRUNC is not necessary.
The issue only happens if we truncate to 0, to any other size it works fine.
Fixed here:
https://lore.kernel.org/linux-btrfs/cover.1771350720.git.fdmanana@xxxxxxxx/
Thanks.
> 4. Create a new hard link to the file in the same directory.
> 5. Sync the directory.
>
> After system crash the file will have the old size (>0) even though the
> file was synced after truncating (O_TRUNC).
>
>
> System info
> ===========
>
> Linux version 6.19.2
>
>
> 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 file_fd;
> int dir_fd;
>
> status = creat("file1", S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH);
> printf("CREAT: %d\n", status);
>
> status = truncate("file1", 1000);
> printf("TRUNCATE: %d\n", status);
>
> sync();
>
> status = open("file1", O_RDWR | O_TRUNC);
> printf("OPEN: %d\n", status);
> file_fd = status;
>
> status = fsync(file_fd);
> printf("FSYNC: %d\n", status);
>
> status = open(".", O_RDONLY | O_DIRECTORY);
> printf("OPEN: %d\n", status);
> dir_fd = status;
>
> status = link("file1", "file2");
> printf("LINK: %d\n", status);
>
> status = fsync(dir_fd);
> printf("FSYNC: %d\n", status);
> }
> // file size is 1000 instead of 0
> ```
>
> 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 file size is 1000 instead of 0.
>