SIGN IN SIGN UP

os/bluestore/BlueFS: reserve the log-extension seq before releasing dirty.lock

_extend_log() bumps dirty.seq_live after _flush_and_sync_log_LD() has
already released dirty.lock. A file that a concurrent
_signal_dirty_to_log_D() registers under the pre-bump seq_live is
stranded: _consume_dirty() does an exact find(seq) and never visits
that bucket, and _clear_dirty_set_stable_D() later erases it while
marking the file clean. The file's op_file_update_inc never reaches
the journal even though fsync() returned success; after a restart,
replay reconstructs a stale fnode and RocksDB reports 'Corruption:
file is too short ... to be an sstable'.

Introduced by e97aa857c241 ("os/bluestore: fix bluefs log runway
enospc"), first released in v19.0.0; Reef is unaffected.

Fix by keeping all seq_live updates under dirty.lock:

- split _maybe_extend_log() into _need_extend_log() and _extend_log();
- _flush_and_sync_log_LD() reserves a dedicated seq for the extension
  transaction atomically with its own seq advance, so no fsync can
  ever register a file under it; _extend_log() only steps log.t.seq;
- the async-compaction site no longer extends the log itself; if the
  runway is short it flushes the log first, which extends it as a
  side effect.

Fixes: https://tracker.ceph.com/issues/79068
Signed-off-by: Ming Lei <ming.lei@clyso.com>
M
Ming Lei committed
2499b4a572b5c9962ad032cda07b0dfbf53b14e7
Parent: 3258ce9