]> git.apps.os.sepia.ceph.com Git - ceph.git/commit
os/bluestore: Fix BlueFS::truncate() 61314/head
authorAdam Kupczyk <akupczyk@ibm.com>
Fri, 10 Jan 2025 08:26:54 +0000 (08:26 +0000)
committerAdam Kupczyk <akupczyk@ibm.com>
Mon, 13 Jan 2025 08:17:16 +0000 (08:17 +0000)
commit7f3601089d41bfc23f530c7bf3fb7efad2d055ec
tree83062d5ed21e8f781af173abf7340b2671a57229
parentf2b5e2fa0a9274c1667fccafa597fff9be7a74b1
os/bluestore: Fix BlueFS::truncate()

In `struct bluefs_fnode_t` there is a vector `extents` and
the vector `extents_index` that is a log2 seek cache.

Until modifications to truncate() we never removed extents from files.
Modified truncate() did not update extents_index.

For example 10 extents long files when truncated to 0 will have:
0 extents, 10 extents_index.
After writing some data to file:
1 extents, 11 extents_index.

Now, `bluefs_fnode_t::seek` will binary search extents_index,
lets say it located seek at item #3.
It will then jump up from #0 extent (that exists) to #3 extent which
does not exist at.
The worst part is that code is now broken, as #3 != extent.end().

There are 3 parts of the fix:
1) assert in `bluefs_fnode_t::seek` to protect against
   jumping outside extents
2) code in BlueFS::truncate to sync up `extents_index` with `extents`
3) dampening down assert in _replay to give a way out of cases
   where incorrect "offset 12345" (12345 is file size) instead of
   "offset 20000" (allocations occupied) was written to log.

Fixes: https://tracker.ceph.com/issues/69481
Signed-off-by: Adam Kupczyk <akupczyk@ibm.com>
src/os/bluestore/BlueFS.cc
src/os/bluestore/bluefs_types.cc
src/os/bluestore/bluefs_types.h