]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph.git/commitdiff
crimson/os/seastore: handle enoent in SeaStore::Shard::stat 68333/head
authorLumir Sliva <61183145+lumir-sliva@users.noreply.github.com>
Sat, 11 Apr 2026 21:18:45 +0000 (23:18 +0200)
committerLumir Sliva <61183145+lumir-sliva@users.noreply.github.com>
Tue, 5 May 2026 11:23:04 +0000 (13:23 +0200)
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>
src/crimson/os/seastore/seastore.cc
src/test/crimson/seastore/test_seastore.cc

index 0189d840b8f7d285d2dfbad473c75e3dd2e0e037..3e12c13161b36c90bf2eea77f812260843774a24 100644 (file)
@@ -1435,6 +1435,9 @@ seastar::future<struct stat> SeaStore::Shard::stat(
     [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"
     }
index 166ad7b3de3e8abddbe62cbe29eab69f99d9ea2f..2034d620f61a7ded921faefb79a8f902411f39cb 100644 (file)
@@ -926,6 +926,16 @@ TEST_P(seastore_test_t, touch_stat_list_remove)
   });
 }
 
+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{