lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [<thread-prev] [day] [month] [year] [list]
Message-ID: <CAL3q7H4e8JPggKYasQA9Cm2UA=iCNuuchEjB0GzYKxPvf4f-FA@mail.gmail.com>
Date: Wed, 3 Dec 2025 17:42:31 +0000
From: Filipe Manana <fdmanana@...nel.org>
To: Vyacheslav Kovalevsky <slava.kovalevskiy.2014@...il.com>
Cc: clm@...com, dsterba@...e.com, linux-btrfs@...r.kernel.org, 
	linux-kernel@...r.kernel.org
Subject: Re: Directory is not persisted after creating 100s of files inside,
 writing to another file and renaming it if system crashes.

On Wed, Dec 3, 2025 at 11:26 AM Vyacheslav Kovalevsky
<slava.kovalevskiy.2014@...il.com> wrote:
>
> Directory entry is not persisted after creating 100s (hundreds) of files inside, writing to another file (with `O_SYNC` flag) and renaming it if system crashes.

There's no need to create hundreds of files, 1 is enough. There's also
no need to open the file with O_SYNC or write data to it, more details
below.

>
>
> Detailed description
> ====================
>
> Hello, we have found another issue with btrfs crash behavior.
>
> In short:
>
> 1. Create and sync an empty file in root directory.
> 2. Make new directory in root directory.
> 3. Open the file with `O_SYNC` flag and write some data (of specific size).

There's no need to O_SYNC, write data of any specific size or even write data.
Just change the file in some way (writing something to it of any size,
or changing uid, gid, or add a xattr, etc) and then fsync it.

> 4. Fill directory with specific number of empty files.

One file is enough.

Fixed by:   https://lore.kernel.org/linux-btrfs/a1b70971f8b73d44695ab6af56b69e0ae1010179.1764783284.git.fdmanana@suse.com/

Thanks.

> 5. Rename the previously written file.
> 6. Sync root directory.
>
> After system crash directory will be missing, although it was synced in the last step.
>
>
> System info
> ===========
>
> Linux version 6.18, also tested on 6.14.11.
>
>
> 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>
>
> #define BUFFER_LEN 1024 // should be at least ~ 528
> #define FILE_N 256      // should be at least ~ 128
>
> int main() {
>    int status;
>    int file_fd;
>    int root_fd;
>
>    int buffer[BUFFER_LEN + 1] = {};
>    for (int i = 0; i < BUFFER_LEN; ++i) {
>      buffer[i] = i;
>    }
>
>    status = creat("file1", S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH);
>    printf("CREAT: %d\n", status);
>    close(status);
>
>    // persist `file1`
>    sync();
>
>    status = mkdir("dir", S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH);
>    printf("MKDIR: %d\n", status);
>
>    // `O_SYNC` is important
>    status = open("file1", O_WRONLY | O_SYNC);
>    printf("OPEN: %d\n", status);
>    file_fd = status;
>
>    status = write(file_fd, buffer, BUFFER_LEN);
>    printf("WRITE: %d\n", status);
>
>    char path[100];
>    // fill directory with a lot of empty files
>    for (int i = 0; i < FILE_N; ++i) {
>      sprintf(path, "dir/%d", i);
>      status = creat(path, S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH);
>      close(status);
>    }
>
>    status = rename("file1", "file2");
>    printf("RENAME: %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);
> }
> // after the crash `dir` is missing
> ```
>
> 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 is missing.
>
>

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ