Skip to content

Commit f6531ff

Browse files
authored
Merge pull request #4721 from rabbitmq/fix-classic-queue-index-v2-on-cow-filesystems
rabbit_classic_queue_index_v2: Support copy-on-write filesystems
2 parents f73a048 + bf394dd commit f6531ff

File tree

1 file changed

+19
-6
lines changed

1 file changed

+19
-6
lines changed

deps/rabbit/src/rabbit_classic_queue_index_v2.erl

Lines changed: 19 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -594,15 +594,20 @@ new_segment_file(Segment, SegmentEntryCount, State = #qi{ segments = Segments })
594594
case file:allocate(Fd, 0, Size) of
595595
ok ->
596596
ok;
597+
%% For filesystems using copy-on-write such as ZFS, file preallocation
598+
%% does not make any sense. For instance, on FreeBSD+ZFS,
599+
%% posix_fallocate(2) fails with `EINVAL'.
600+
%%
601+
%% FIXME: Filling the file with zeroes is counter-productive because
602+
%% it eats free space for no benefits and even worsen situations where
603+
%% the disk is short on free space. However we still do it because the
604+
%% rest of the code assumes that the file is preallocated.
605+
{error, einval} ->
606+
fill_file_with_zeroes(Fd, Size);
597607
%% On some platforms file:allocate is not supported (e.g. Windows).
598608
%% In that case we fill the file with zeroes manually.
599609
{error, enotsup} ->
600-
ok = file:write(Fd, <<0:Size/unit:8>>),
601-
{ok, 0} = file:position(Fd, bof),
602-
%% We do a full GC immediately after because we do not want
603-
%% to keep around the large binary we used to fill the file.
604-
_ = garbage_collect(),
605-
ok
610+
fill_file_with_zeroes(Fd, Size)
606611
end,
607612
%% We then write the segment file header. It contains
608613
%% some useful info and some reserved bytes for future use.
@@ -620,6 +625,14 @@ new_segment_file(Segment, SegmentEntryCount, State = #qi{ segments = Segments })
620625
State#qi{ segments = Segments#{Segment => 1},
621626
fds = OpenFds#{Segment => Fd} }.
622627

628+
fill_file_with_zeroes(Fd, Size) ->
629+
ok = file:write(Fd, <<0:Size/unit:8>>),
630+
{ok, 0} = file:position(Fd, bof),
631+
%% We do a full GC immediately after because we do not want
632+
%% to keep around the large binary we used to fill the file.
633+
_ = garbage_collect(),
634+
ok.
635+
623636
%% We try to keep the number of FDs open at 4 at a maximum.
624637
%% Under normal circumstances we will end up with 1 or 2
625638
%% open (roughly one for reading, one for writing, when

0 commit comments

Comments
 (0)