diff options
author | Eric Wong <e@80x24.org> | 2021-10-21 21:10:32 +0000 |
---|---|---|
committer | Eric Wong <e@80x24.org> | 2021-10-22 00:54:51 +0000 |
commit | 4cd7a78f3b8c03670e2d77675229472506eee1eb (patch) | |
tree | 2a0e89de3e77b70962e509d41883518fb6574dde /lib/PublicInbox/LeiStore.pm | |
parent | 2c354e17694da744c6dc1ab19c14af3d456b28bb (diff) | |
download | public-inbox-4cd7a78f3b8c03670e2d77675229472506eee1eb.tar.gz |
One syscall is better than two for atomicity in Maildirs. This means there's no window where another process can see both the old and new file at the same time (link && unlink), nor a window where we might inadvertantly clobber an existing file if we were to do `stat && rename'.
Diffstat (limited to 'lib/PublicInbox/LeiStore.pm')
-rw-r--r-- | lib/PublicInbox/LeiStore.pm | 8 |
1 files changed, 3 insertions, 5 deletions
diff --git a/lib/PublicInbox/LeiStore.pm b/lib/PublicInbox/LeiStore.pm index 16e7d302..f1316229 100644 --- a/lib/PublicInbox/LeiStore.pm +++ b/lib/PublicInbox/LeiStore.pm @@ -32,6 +32,7 @@ use POSIX (); use IO::Handle (); # ->autoflush use Sys::Syslog qw(syslog openlog); use Errno qw(EEXIST ENOENT); +use PublicInbox::Syscall qw(rename_noreplace); sub new { my (undef, $dir, $opt) = @_; @@ -185,10 +186,7 @@ sub export1_kw_md ($$$$$) { my $dst = "$mdir/cur/$bn"; for my $d (@try) { my $src = "$mdir/$d/$orig"; - if (link($src, $dst)) { - if (!unlink($src) and $! != ENOENT) { - syslog('warning', "unlink($src): $!"); - } + if (rename_noreplace($src, $dst)) { # TODO: verify oidbin? $self->{lms}->mv_src("maildir:$mdir", $oidbin, \$orig, $bn); @@ -196,7 +194,7 @@ sub export1_kw_md ($$$$$) { } elsif ($! == EEXIST) { # lost race with "lei export-kw"? return; } elsif ($! != ENOENT) { - syslog('warning', "link($src -> $dst): $!"); + syslog('warning', "rename_noreplace($src -> $dst): $!"); } } for (@try) { return if -e "$mdir/$_/$orig" }; |