--- author: Las Safin date: "2021-07-07" keywords: - f2fs - swap - linux title: F2FS swap files broken and the arcane ritual to fix them ... [Jump to the fix](#the-fix) A few days ago, after updating nixpkgs on my ODROID N2 to a reivision with Linux 5.13, it began mysteriously crashing. Eventually I figured out that it happens when it starts swapping to the swap file, and I noticed I even get an error when I enable the swap file: ```default [...] F2FS-fs (dm-0): Swapfile does not align to section ``` What the fuck does this mean? - I thought then. I began searching the internet, but unfortunately, very little comes up, except some mails from lkml.org: - - In the second link, something that *seems* like a solution is described: > Subject: Re: [PATCH v2] f2fs: avoid swapon failure by giving a warning first > ... > The final solution can be migrating blocks to form a section-aligned file > internally. Meanwhile, let's ask users to do that when preparing the swap > file initially like: > > ```default > 1) create() > 2) ioctl(F2FS_IOC_SET_PIN_FILE) > 3) fallocate() > ``` The message isn't very understandable, but thankfully we have a clue: `F2FS_IOC_SET_PIN_FILE`. Looking at the [source code for F2FS](https://github.com/torvalds/linux/blob/v5.13/fs/f2fs/file.c#L4163), and finding [this](https://www.mail-archive.com/linux-kernel@vger.kernel.org/msg2192134.html), we finally have a real explanation of what it does: > Yes, this is persistent. `F2FS_IOC_SET_PIN_FILE` ioctl is to prevent > file data from moving and being garbage collected, and further update > to the file will be handled in in-place update manner. > I don't see any document on this, but you can find the below in > Documentation/filesystems/f2fs.rst > > However, once F2FS receives `ioctl(fd, F2FS_IOC_SET_PIN_FILE)` in prior to > `fallocate(fd, DEFAULT_MODE)`, it allocates on-disk blocks addresses having > zero or random data, which is useful to the below scenario where: > > 1. `create(fd)` > 2. `ioctl(fd, F2FS_IOC_SET_PIN_FILE)` > 3. `fallocate(fd, 0, 0, size)` > 4. `address = fibmap(fd, offset)` > 5. `open(blkdev)` > 6. `write(blkdev, address)` F2FS is a log-structured file system, which means that writes are generally written sequentially in a log-like structure. When the kernel uses the file as swap, it updates it in-place. By marking the file as pinned in F2FS, F2FS will make sure that it's updated in place. This doesn't explain why it worked fine before, but let's try marking our swap file with this ioctl: # The fix ```c #!/usr/bin/env -S tcc -run #define _GNU_SOURCE #include #include #include #include #include #include #include #include int main() { int fd = creat("./theswapfile", S_IRUSR | S_IWUSR); uint32_t pin = 1; if (fd == -1) { fprintf(stderr, "Error at creat: %i\n", errno); return 1; } int r = ioctl(fd, F2FS_IOC_SET_PIN_FILE, &pin); if (r == -1) { fprintf(stderr, "Error at ioctl: %i\n", errno); return 1; } uint64_t len = 8LLU * 1024LLU * 1024LLU * 1024LLU; // 8 GiB fprintf(stderr, "len: %llu\n", len); r = fallocate(fd, 0, 0, len); if (r == -1) { fprintf(stderr, "Error at fallocate: %i\n", errno); return 1; } r = close(fd); if (r == -1) { fprintf(stderr, "Error at close: %i\n", errno); return 1; } return 0; } ``` Success! The `uint32_t pin` parameter for `F2FS_IOC_SET_PIN_FILE` seems to act as a boolean, judging from [this](https://github.com/torvalds/linux/blob/v5.13/fs/f2fs/file.c#L3136). When 0, it seems to set it to unpinned, and otherwise it seems to set it to pinned. Unfortunately for me though, my machine still crashes occasionally, but it doesn't seem to be related to swap anymore at least! -------- # About me Type theorist. Rolling my own crypto. - E-mail: mdwuaidiuawhdiuhe`@`{=html};lajxujxujuxjujus.rs - GitHub: [\@L-as](https://github.com/L-as) - Matrix: [\@Las:matrix.org](https://matrix.to/#/@Las:matrix.org) # Posts - [All you need is higher kinded types](/blog/all-you-need-is-hkt-s.html) - 2023-01-13 - [Using Haskell as my shell](/blog/haskell-as-shell.html) - 2021-07-23 - [vfork, close_range, and execve for launching processes in Procex](/blog/vfork_close_execve.html) - 2021-07-20 - [F2FS swap files broken and the arcane ritual to fix them](/blog/f2fs.html) - 2021-07-07 This page has a [markdown version](./f2fs.md) [Atom Feed](/atom.xml) [Public PGP key (6B66 1F36 59D3 BAE7 0561 862E EA8E 9467 5140 F7F4)](/public-pgp-key.txt)