crimson/osd: guard recovery clone overlap with try_lock_for_read
Crimson recovery could use a neighbor clone as a clone_subset source
during osd_recover_clone_overlap without checking whether that clone
was safe to read. Classic OSD takes a read lock on the neighbor clone
via try_lock_for_read() before using it.
Under snap trim + recovery stress, recovery could clone_range from a
clone that snap trim was modifying, producing wrong object content
(ceph_test_rados: incorrect buffer at pos
1462272).
calc_clone_subsets() and calc_head_subsets() now return clone overlap
candidates in preference order only. ReplicatedRecoveryBackend locks
the first usable neighbor clone from each list and holds those read
locks until push/pull recovery completes. RecoveryCloneLockManager
releases locks in its destructor so move-assign cannot leak a held
lock and block snap trim.
Fixes: https://tracker.ceph.com/issues/76499
Signed-off-by: Kautilya Tripathi <kautilya.tripathi@ibm.com>