1818#include < map>
1919#include < string>
2020#include < sisl/logging/logging.h>
21+ #include < sisl/utility/obj_life_counter.hpp>
22+ #include < homestore/crc.h>
2123#include < homestore/homestore.hpp>
2224#include < homestore/index/index_table.hpp>
2325#include < homestore/superblk_handler.hpp>
@@ -30,6 +32,14 @@ namespace homeblocks {
3032
3133class Volume ;
3234
35+ ENUM (HomeBlksMsgType, uint8_t , READ, WRITE, UNMAP);
36+
37+ struct VolJournalEntry {
38+ lba_t start_lba;
39+ lba_count_t nlbas;
40+ uint16_t num_old_blks;
41+ };
42+
3343class HomeBlocksImpl : public HomeBlocks , public VolumeManager , public std ::enable_shared_from_this< HomeBlocksImpl > {
3444 struct homeblks_sb_t {
3545 uint64_t magic;
@@ -119,6 +129,9 @@ class HomeBlocksImpl : public HomeBlocks, public VolumeManager, public std::enab
119129
120130 void on_init_complete ();
121131
132+ void on_write (int64_t lsn, const sisl::blob& header, const sisl::blob& key,
133+ const std::vector< homestore::MultiBlkId >& blkids, cintrusive< homestore::repl_req_ctx >& ctx);
134+
122135private:
123136 // Should only be called for first-time-boot
124137 void superblk_init ();
@@ -133,6 +146,10 @@ class HomeBlocksImpl : public HomeBlocks, public VolumeManager, public std::enab
133146 // recovery apis
134147 void on_hb_meta_blk_found (sisl::byte_view const & buf, void * cookie);
135148 void on_vol_meta_blk_found (sisl::byte_view const & buf, void * cookie);
149+
150+ VolumeManager::Result< folly::Unit > write_to_index (const VolumePtr& vol_ptr, const vol_interface_req_ptr& vol_req,
151+ lba_t start_lba, lba_t end_lba,
152+ std::unordered_map< lba_t , BlockInfo >& blocks_info);
136153};
137154
138155class HBIndexSvcCB : public homestore ::IndexServiceCallbacks {
@@ -147,4 +164,87 @@ class HBIndexSvcCB : public homestore::IndexServiceCallbacks {
147164private:
148165 HomeBlocksImpl* hb_;
149166};
167+
168+ const homestore::csum_t init_crc_16 = 0x8005 ;
169+
170+ struct HomeBlksMessageHeader {
171+ HomeBlksMessageHeader () = default ;
172+ HomeBlksMsgType msg_type;
173+ volume_id_t volume_id;
174+
175+ std::string to_string () const {
176+ return fmt::format (" msg_type={}volume={}\n " , enum_name (msg_type), boost::uuids::to_string (volume_id));
177+ }
178+ };
179+
180+ struct homeblks_repl_ctx : public homestore ::repl_req_ctx {
181+ sisl::io_blob_safe hdr_buf_;
182+ sisl::io_blob_safe key_buf_;
183+
184+ // Data bufs corresponding to data_sgs_. Since data_sgs are raw pointers, we need to keep the data bufs alive
185+ folly::small_vector< sisl::io_blob_safe, 3 > data_bufs_;
186+ sisl::sg_list data_sgs_;
187+
188+ homeblks_repl_ctx (uint32_t hdr_extn_size, uint32_t key_size = 0 ) : homestore::repl_req_ctx{} {
189+ hdr_buf_ = std::move (sisl::io_blob_safe{uint32_cast (sizeof (HomeBlksMessageHeader) + hdr_extn_size), 0 });
190+ new (hdr_buf_.bytes ()) HomeBlksMessageHeader ();
191+
192+ if (key_size) { key_buf_ = std::move (sisl::io_blob_safe{key_size, 0 }); }
193+ data_sgs_.size = 0 ;
194+ }
195+
196+ ~homeblks_repl_ctx () {
197+ if (hdr_buf_.bytes ()) { header ()->~HomeBlksMessageHeader (); }
198+ }
199+
200+ template < typename T >
201+ T* to () {
202+ return r_cast< T* >(this );
203+ }
204+
205+ HomeBlksMessageHeader* header () { return r_cast< HomeBlksMessageHeader* >(hdr_buf_.bytes ()); }
206+ uint8_t * header_extn () { return hdr_buf_.bytes () + sizeof (HomeBlksMessageHeader); }
207+
208+ sisl::io_blob_safe& header_buf () { return hdr_buf_; }
209+ sisl::io_blob_safe const & cheader_buf () const { return hdr_buf_; }
210+
211+ sisl::io_blob_safe& key_buf () { return key_buf_; }
212+ sisl::io_blob_safe const & ckey_buf () const { return key_buf_; }
213+
214+ void add_data_sg (uint8_t * buf, uint32_t size) {
215+ data_sgs_.iovs .emplace_back (iovec{.iov_base = buf, .iov_len = size});
216+ data_sgs_.size += size;
217+ }
218+
219+ void add_data_sg (sisl::io_blob_safe&& buf) {
220+ add_data_sg (buf.bytes (), buf.size ());
221+ data_bufs_.emplace_back (std::move (buf));
222+ }
223+
224+ sisl::sg_list& data_sgs () { return data_sgs_; }
225+ std::string data_sgs_string () const {
226+ fmt::memory_buffer buf;
227+ fmt::format_to (fmt::appender (buf), " total_size={} iovcnt={} [" , data_sgs_.size , data_sgs_.iovs .size ());
228+ for (auto const & iov : data_sgs_.iovs ) {
229+ fmt::format_to (fmt::appender (buf), " <base={},len={}> " , iov.iov_base , iov.iov_len );
230+ }
231+ fmt::format_to (fmt::appender (buf), " ]" );
232+ return fmt::to_string (buf);
233+ }
234+ };
235+
236+ template < typename T >
237+ struct repl_result_ctx : public homeblks_repl_ctx {
238+ folly::Promise< T > promise_;
239+ VolumePtr vol_ptr_{nullptr };
240+
241+ template < typename ... Args >
242+ static intrusive< repl_result_ctx< T > > make (Args&&... args) {
243+ return intrusive< repl_result_ctx< T > >{new repl_result_ctx< T >(std::forward< Args >(args)...)};
244+ }
245+
246+ repl_result_ctx (uint32_t hdr_extn_size, uint32_t key_size = 0 ) : homeblks_repl_ctx{hdr_extn_size, key_size} {}
247+ folly::SemiFuture< T > result () { return promise_.getSemiFuture (); }
248+ };
249+
150250} // namespace homeblocks
0 commit comments