stat() aborts via assert_all when get_onode() returns ENOENT for a
non-existent object. But get_onode() explicitly declares enoent as a
valid error (onode_manager.h:36-40), and replicated_recovery_backend
calls stat() during push-based recovery on objects that haven't been
pulled yet.
Handle enoent by returning an empty struct stat — same pattern as
exists() (line 1207) and the !store_active early return (line 1384).
The recovery code in replicated_recovery_backend.cc:831-840 already
handles st_size=0 correctly.
Add a unit test that stats a non-existent object to verify it returns
an empty struct instead of aborting.
Fixes: https://tracker.ceph.com/issues/75814
Signed-off-by: Lumir Sliva <61183145+lumir-sliva@users.noreply.github.com>
[this, oid](auto &t, auto &onode) {
return _stat(t, onode, oid);
}).handle_error(
+ crimson::ct_error::enoent::handle([] {
+ return seastar::make_ready_future<struct stat>();
+ }),
crimson::ct_error::assert_all{
"Invalid error in SeaStoreS::stat"
}
});
}
+TEST_P(seastore_test_t, stat_nonexistent)
+{
+ run_async([this] {
+ auto st = sharded_seastore->stat(
+ coll,
+ make_oid(99)).get();
+ EXPECT_EQ(st.st_size, 0);
+ });
+}
+
using bound_t = seastore_test_t::bound_t;
constexpr unsigned MAX_LIMIT = std::numeric_limits<unsigned>::max();
static const seastore_test_t::list_test_cases_t temp_list_cases{