219 lines
		
	
	
		
			5.6 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
			
		
		
	
	
			219 lines
		
	
	
		
			5.6 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
// Copyright (C) 2018 Red Hat, Inc. All rights reserved.
 | 
						|
//
 | 
						|
// This file is part of the thin-provisioning-tools source.
 | 
						|
//
 | 
						|
// thin-provisioning-tools is free software: you can redistribute it
 | 
						|
// and/or modify it under the terms of the GNU General Public License
 | 
						|
// as published by the Free Software Foundation, either version 3 of
 | 
						|
// the License, or (at your option) any later version.
 | 
						|
//
 | 
						|
// thin-provisioning-tools is distributed in the hope that it will be
 | 
						|
// useful, but WITHOUT ANY WARRANTY; without even the implied warranty
 | 
						|
// of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
						|
// GNU General Public License for more details.
 | 
						|
//
 | 
						|
// You should have received a copy of the GNU General Public License along
 | 
						|
// with thin-provisioning-tools.  If not, see
 | 
						|
// <http://www.gnu.org/licenses/>.
 | 
						|
 | 
						|
#ifndef THIN_PROVISIONING_THIN_JOURNAL_H
 | 
						|
#define THIN_PROVISIONING_THIN_JOURNAL_H
 | 
						|
 | 
						|
#include "persistent-data/block.h"
 | 
						|
 | 
						|
#include <vector>
 | 
						|
 | 
						|
//----------------------------------------------------------------
 | 
						|
 | 
						|
namespace thin_provisioning {
 | 
						|
	uint32_t const JOURNAL_BLOCK_SIZE = 4096;
 | 
						|
	uint32_t const JOURNAL_CHUNK_SIZE = 32;
 | 
						|
	uint32_t const JOURNAL_NR_CHUNKS = (4096 / JOURNAL_CHUNK_SIZE);
 | 
						|
 | 
						|
	class byte_stream {
 | 
						|
	public:
 | 
						|
		byte_stream(persistent_data::block_manager::ptr bm);
 | 
						|
 | 
						|
		void read_bytes(uint8_t *b, uint8_t *e);
 | 
						|
 | 
						|
	private:
 | 
						|
		void next_block_();
 | 
						|
		size_t read_some_(uint8_t *b, uint8_t *e);
 | 
						|
 | 
						|
		persistent_data::block_manager::ptr bm_;
 | 
						|
 | 
						|
		uint64_t current_block_;
 | 
						|
		uint64_t cursor_;
 | 
						|
	};
 | 
						|
 | 
						|
	//---------------------------------
 | 
						|
 | 
						|
	class journal_visitor;
 | 
						|
 | 
						|
	struct journal_msg {
 | 
						|
		journal_msg(bool success);
 | 
						|
 | 
						|
		virtual ~journal_msg() {}
 | 
						|
		virtual void visit(journal_visitor &v) const = 0;
 | 
						|
 | 
						|
		bool success_;
 | 
						|
	};
 | 
						|
 | 
						|
	struct open_journal_msg : public journal_msg {
 | 
						|
		open_journal_msg(uint64_t nr_metadata_blocks);
 | 
						|
		virtual void visit(journal_visitor &v) const;
 | 
						|
		uint64_t nr_metadata_blocks_;
 | 
						|
	};
 | 
						|
 | 
						|
	struct close_journal_msg : public journal_msg {
 | 
						|
		close_journal_msg();
 | 
						|
		virtual void visit(journal_visitor &v) const;
 | 
						|
	};
 | 
						|
 | 
						|
	struct block_msg : public journal_msg {
 | 
						|
		block_msg(bool success, uint64_t index);
 | 
						|
		uint64_t index_;
 | 
						|
	};
 | 
						|
 | 
						|
	struct read_lock_msg : public block_msg {
 | 
						|
		read_lock_msg(bool success, uint64_t index);
 | 
						|
		virtual void visit(journal_visitor &v) const;
 | 
						|
	};
 | 
						|
 | 
						|
	struct write_lock_msg : public block_msg {
 | 
						|
		write_lock_msg(bool success, uint64_t index);
 | 
						|
		virtual void visit(journal_visitor &v) const;
 | 
						|
	};
 | 
						|
 | 
						|
	struct zero_lock_msg : public block_msg {
 | 
						|
		zero_lock_msg(bool success, uint64_t index);
 | 
						|
		virtual void visit(journal_visitor &v) const;
 | 
						|
	};
 | 
						|
 | 
						|
	struct try_read_lock_msg : public block_msg {
 | 
						|
		try_read_lock_msg(bool success, uint64_t index);
 | 
						|
		virtual void visit(journal_visitor &v) const;
 | 
						|
	};
 | 
						|
 | 
						|
	struct delta {
 | 
						|
		delta(uint32_t offset, std::vector<uint8_t> &bytes)
 | 
						|
			: offset_(offset),
 | 
						|
			  bytes_(bytes) {
 | 
						|
		}
 | 
						|
 | 
						|
		uint32_t offset_;
 | 
						|
		std::vector<uint8_t> bytes_;
 | 
						|
	};
 | 
						|
 | 
						|
	using delta_list = std::vector<delta>;
 | 
						|
 | 
						|
	struct unlock_msg : public block_msg {
 | 
						|
		unlock_msg(bool success, uint64_t index, delta_list const &deltas);
 | 
						|
		virtual void visit(journal_visitor &v) const;
 | 
						|
 | 
						|
		delta_list deltas_;
 | 
						|
	};
 | 
						|
 | 
						|
	struct verify_msg : public block_msg {
 | 
						|
		verify_msg(bool success, uint64_t index);
 | 
						|
		virtual void visit(journal_visitor &v) const;
 | 
						|
	};
 | 
						|
 | 
						|
	struct prepare_msg : public block_msg {
 | 
						|
		prepare_msg(bool success, uint64_t index);
 | 
						|
		virtual void visit(journal_visitor &v) const;
 | 
						|
	};
 | 
						|
 | 
						|
	struct flush_msg : public journal_msg {
 | 
						|
		flush_msg(bool success);
 | 
						|
		virtual void visit(journal_visitor &v) const;
 | 
						|
	};
 | 
						|
 | 
						|
	struct flush_and_unlock_msg : public block_msg {
 | 
						|
		flush_and_unlock_msg(bool success, uint64_t index, delta_list const &deltas);
 | 
						|
		virtual void visit(journal_visitor &v) const;
 | 
						|
 | 
						|
		delta_list deltas_;
 | 
						|
	};
 | 
						|
 | 
						|
	struct prefetch_msg : public block_msg {
 | 
						|
		prefetch_msg(bool success, uint64_t index);
 | 
						|
		virtual void visit(journal_visitor &v) const;
 | 
						|
	};
 | 
						|
 | 
						|
	struct set_read_only_msg : public journal_msg {
 | 
						|
		set_read_only_msg();
 | 
						|
		virtual void visit(journal_visitor &v) const;
 | 
						|
	};
 | 
						|
 | 
						|
	struct set_read_write_msg : public journal_msg {
 | 
						|
		set_read_write_msg();
 | 
						|
		virtual void visit(journal_visitor &v) const;
 | 
						|
	};
 | 
						|
 | 
						|
	struct journal_visitor {
 | 
						|
	public:
 | 
						|
		virtual ~journal_visitor() {};
 | 
						|
 | 
						|
		void visit(journal_msg const &msg) {
 | 
						|
			msg.visit(*this);
 | 
						|
		}
 | 
						|
 | 
						|
		virtual void visit(open_journal_msg const &msg) = 0;
 | 
						|
		virtual void visit(close_journal_msg const &msg) = 0;
 | 
						|
		virtual void visit(read_lock_msg const &msg) = 0;
 | 
						|
		virtual void visit(write_lock_msg const &msg) = 0;
 | 
						|
		virtual void visit(zero_lock_msg const &msg) = 0;
 | 
						|
		virtual void visit(try_read_lock_msg const &msg) = 0;
 | 
						|
		virtual void visit(unlock_msg const &msg) = 0;
 | 
						|
		virtual void visit(verify_msg const &msg) = 0;
 | 
						|
		virtual void visit(prepare_msg const &msg) = 0;
 | 
						|
		virtual void visit(flush_msg const &msg) = 0;
 | 
						|
		virtual void visit(flush_and_unlock_msg const &msg) = 0;
 | 
						|
		virtual void visit(prefetch_msg const &msg) = 0;
 | 
						|
		virtual void visit(set_read_only_msg const &msg) = 0;
 | 
						|
		virtual void visit(set_read_write_msg const &msg) = 0;
 | 
						|
	};
 | 
						|
 | 
						|
	enum msg_type {
 | 
						|
		MT_OPEN_JOURNAL,
 | 
						|
		MT_CLOSE_JOURNAL,
 | 
						|
 | 
						|
		MT_READ_LOCK,
 | 
						|
		MT_WRITE_LOCK,
 | 
						|
		MT_ZERO_LOCK,
 | 
						|
		MT_TRY_READ_LOCK,
 | 
						|
		MT_UNLOCK,
 | 
						|
		MT_VERIFY,
 | 
						|
		MT_PREPARE,
 | 
						|
		MT_FLUSH,
 | 
						|
		MT_FLUSH_AND_UNLOCK,
 | 
						|
		MT_PREFETCH,
 | 
						|
		MT_SET_READ_ONLY,
 | 
						|
		MT_SET_READ_WRITE,
 | 
						|
	};
 | 
						|
 | 
						|
	class journal {
 | 
						|
	public:
 | 
						|
		journal(persistent_data::block_manager::ptr bm);
 | 
						|
		void read_journal(struct journal_visitor &v);
 | 
						|
 | 
						|
	private:
 | 
						|
		bool read_delta_(delta_list &ds);
 | 
						|
		delta_list read_deltas_();
 | 
						|
		bool read_one_(struct journal_visitor &v);
 | 
						|
 | 
						|
		template <typename T> T read_() {
 | 
						|
			T r;
 | 
						|
			in_.read_bytes(reinterpret_cast<uint8_t *>(&r), reinterpret_cast<uint8_t *>(&r + 1));
 | 
						|
			return r;
 | 
						|
		}
 | 
						|
 | 
						|
		byte_stream in_;
 | 
						|
	};
 | 
						|
}
 | 
						|
 | 
						|
//----------------------------------------------------------------
 | 
						|
 | 
						|
#endif
 |