All of lore.kernel.org
 help / color / mirror / Atom feed
From: Chris Murphy <lists@colorremedies.com>
To: Linux FS Devel <linux-fsdevel@vger.kernel.org>
Subject: Is rename(2) atomic on FAT?
Date: Mon, 21 Oct 2019 21:57:13 +0200	[thread overview]
Message-ID: <CAJCQCtQ38W2r7Cuu5ieKRQizeKF0tf--3Z8yOJeeR+ZZ4S6CVQ@mail.gmail.com> (raw)

http://man7.org/linux/man-pages/man2/rename.2.html

Use case is atomically updating bootloader configuration on EFI System
partitions. Some bootloader implementations have configuration files
bigger than 512 bytes, which could possibly be torn on write. But I'm
also not sure what write order FAT uses.

1.
FAT32 file system is mounted at /boot/efi

2.
# echo "hello" > /boot/efi/tmp/test.txt
# mv /boot/efi/tmp/test.txt /boot/efi/EFI/fedora/

3.
When I strace the above mv command I get these lines:
ioctl(0, TCGETS, {B38400 opost isig icanon echo ...}) = 0
renameat2(AT_FDCWD, "/boot/efi/tmp/test.txt", AT_FDCWD,
"/boot/efi/EFI/fedora/", RENAME_NOREPLACE) = -1 EEXIST (File exists)
stat("/boot/efi/EFI/fedora/", {st_mode=S_IFDIR|0700, st_size=1024, ...}) = 0
renameat2(AT_FDCWD, "/boot/efi/tmp/test.txt", AT_FDCWD,
"/boot/efi/EFI/fedora/test.txt", RENAME_NOREPLACE) = 0
lseek(0, 0, SEEK_CUR)                   = -1 ESPIPE (Illegal seek)
close(0)

I can't tell from documentation if renameat2() with flag
RENAME_NOREPLACE is atomic, assuming the file doesn't exist at
destination.

4.
Do it again exactly as before, small change
# echo "hello" > /boot/efi/tmp/test.txt
# mv /boot/efi/tmp/test.txt /boot/efi/EFI/fedora/

5.
The strace shows fallback to rename()

ioctl(0, TCGETS, {B38400 opost isig icanon echo ...}) = 0
renameat2(AT_FDCWD, "/boot/efi/tmp/test.txt", AT_FDCWD,
"/boot/efi/EFI/fedora/", RENAME_NOREPLACE) = -1 EEXIST (File exists)
stat("/boot/efi/EFI/fedora/", {st_mode=S_IFDIR|0700, st_size=1024, ...}) = 0
renameat2(AT_FDCWD, "/boot/efi/tmp/test.txt", AT_FDCWD,
"/boot/efi/EFI/fedora/test.txt", RENAME_NOREPLACE) = -1 EEXIST (File
exists)
lstat("/boot/efi/tmp/test.txt", {st_mode=S_IFREG|0700, st_size=7, ...}) = 0
newfstatat(AT_FDCWD, "/boot/efi/EFI/fedora/test.txt",
{st_mode=S_IFREG|0700, st_size=6, ...}, AT_SYMLINK_NOFOLLOW) = 0
geteuid()                               = 0
rename("/boot/efi/tmp/test.txt", "/boot/efi/EFI/fedora/test.txt") = 0
lseek(0, 0, SEEK_CUR)                   = -1 ESPIPE (Illegal seek)
close(0)                                = 0


Per documentation that should be atomic. So the questions are, are
both atomic, or neither atomice, and if not what should be used to
ensure bootloader updates are atomic.

There are plausibly three kinds:

A. write a new file with file name that doesn't previously exist
B. write a new file with a new file name, then do a rename stomping on
the old one
C. overwrite an existing file

It seems C is risky. It probably isn't atomic and can't be made to be
atomic on FAT.


-- 
Chris Murphy

             reply	other threads:[~2019-10-21 19:57 UTC|newest]

Thread overview: 22+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2019-10-21 19:57 Chris Murphy [this message]
2019-10-21 21:44 ` Is rename(2) atomic on FAT? Richard Weinberger
2019-10-22 10:54   ` Pali Rohár
2019-10-23  0:10     ` Chris Murphy
2019-10-23 11:50       ` Pali Rohár
2019-10-23 14:21         ` Chris Murphy
2019-10-23 17:16           ` Pali Rohár
2019-10-23 19:18             ` Chris Murphy
2019-10-23 21:21             ` Richard Weinberger
2019-10-23 21:56               ` Chris Murphy
2019-10-23 22:22                 ` Richard Weinberger
2019-10-24 21:46                   ` Chris Murphy
2019-10-24 21:57                     ` Pali Rohár
2019-10-24 22:19                       ` Chris Murphy
2019-10-24 22:16                     ` Richard Weinberger
2019-10-24 22:26                       ` Chris Murphy
2019-10-24 22:33                         ` Richard Weinberger
2019-10-25  9:22                           ` Chris Murphy
2019-10-25  9:50                             ` Richard Weinberger
2019-10-23 12:53       ` Colin Walters
2019-10-23 14:24         ` Chris Murphy
2019-10-23 17:26           ` Colin Walters

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=CAJCQCtQ38W2r7Cuu5ieKRQizeKF0tf--3Z8yOJeeR+ZZ4S6CVQ@mail.gmail.com \
    --to=lists@colorremedies.com \
    --cc=linux-fsdevel@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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.