X-Git-Url: https://gerrit.opnfv.org/gerrit/gitweb?a=blobdiff_plain;f=src%2Fceph%2Fsrc%2Flibrbd%2FBlockGuard.h;fp=src%2Fceph%2Fsrc%2Flibrbd%2FBlockGuard.h;h=0000000000000000000000000000000000000000;hb=7da45d65be36d36b880cc55c5036e96c24b53f00;hp=4c371580c1f183320a185e14b556916df4673a41;hpb=691462d09d0987b47e112d6ee8740375df3c51b2;p=stor4nfv.git diff --git a/src/ceph/src/librbd/BlockGuard.h b/src/ceph/src/librbd/BlockGuard.h deleted file mode 100644 index 4c37158..0000000 --- a/src/ceph/src/librbd/BlockGuard.h +++ /dev/null @@ -1,174 +0,0 @@ -// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*- -// vim: ts=8 sw=2 smarttab - -#ifndef CEPH_LIBRBD_IO_BLOCK_GUARD_H -#define CEPH_LIBRBD_IO_BLOCK_GUARD_H - -#include "include/int_types.h" -#include "common/dout.h" -#include "common/Mutex.h" -#include -#include -#include -#include -#include "include/assert.h" - -#define dout_subsys ceph_subsys_rbd -#undef dout_prefix -#define dout_prefix *_dout << "librbd::BlockGuard: " << this << " " \ - << __func__ << ": " - -namespace librbd { - -struct BlockExtent { - uint64_t block_start = 0; - uint64_t block_end = 0; - - BlockExtent() { - } - BlockExtent(uint64_t block_start, uint64_t block_end) - : block_start(block_start), block_end(block_end) { - } -}; - -struct BlockGuardCell { -}; - -/** - * Helper class to restrict and order concurrent IO to the same block. The - * definition of a block is dependent upon the user of this class. It might - * represent a backing object, 512 byte sectors, etc. - */ -template -class BlockGuard { -private: - struct DetainedBlockExtent; - -public: - typedef std::list BlockOperations; - - BlockGuard(CephContext *cct) - : m_cct(cct), m_lock("librbd::BlockGuard::m_lock") { - } - - BlockGuard(const BlockGuard&) = delete; - BlockGuard &operator=(const BlockGuard&) = delete; - - /** - * Detain future IO for a range of blocks. the guard will assume - * ownership of the provided operation if the operation is blocked. - * @return 0 upon success and IO can be issued - * >0 if the IO is blocked, - * <0 upon error - */ - int detain(const BlockExtent &block_extent, BlockOperation *block_operation, - BlockGuardCell **cell) { - Mutex::Locker locker(m_lock); - ldout(m_cct, 20) << "block_start=" << block_extent.block_start << ", " - << "block_end=" << block_extent.block_end << ", " - << "free_slots=" << m_free_detained_block_extents.size() - << dendl; - - DetainedBlockExtent *detained_block_extent; - auto it = m_detained_block_extents.find(block_extent); - if (it != m_detained_block_extents.end()) { - // request against an already detained block - detained_block_extent = &(*it); - if (block_operation != nullptr) { - detained_block_extent->block_operations.emplace_back( - std::move(*block_operation)); - } - - // alert the caller that the IO was detained - *cell = nullptr; - return detained_block_extent->block_operations.size(); - } else { - if (!m_free_detained_block_extents.empty()) { - detained_block_extent = &m_free_detained_block_extents.front(); - detained_block_extent->block_operations.clear(); - m_free_detained_block_extents.pop_front(); - } else { - ldout(m_cct, 20) << "no free detained block cells" << dendl; - m_detained_block_extent_pool.emplace_back(); - detained_block_extent = &m_detained_block_extent_pool.back(); - } - - detained_block_extent->block_extent = block_extent; - m_detained_block_extents.insert(*detained_block_extent); - *cell = reinterpret_cast(detained_block_extent); - return 0; - } - } - - /** - * Release any detained IO operations from the provided cell. - */ - void release(BlockGuardCell *cell, BlockOperations *block_operations) { - Mutex::Locker locker(m_lock); - - assert(cell != nullptr); - auto &detained_block_extent = reinterpret_cast( - *cell); - ldout(m_cct, 20) << "block_start=" - << detained_block_extent.block_extent.block_start << ", " - << "block_end=" - << detained_block_extent.block_extent.block_end << ", " - << "pending_ops=" - << (detained_block_extent.block_operations.empty() ? - 0 : detained_block_extent.block_operations.size() - 1) - << dendl; - - *block_operations = std::move(detained_block_extent.block_operations); - m_detained_block_extents.erase(detained_block_extent.block_extent); - m_free_detained_block_extents.push_back(detained_block_extent); - } - -private: - struct DetainedBlockExtent : public boost::intrusive::list_base_hook<>, - public boost::intrusive::set_base_hook<> { - BlockExtent block_extent; - BlockOperations block_operations; - }; - - struct DetainedBlockExtentKey { - typedef BlockExtent type; - const BlockExtent &operator()(const DetainedBlockExtent &value) { - return value.block_extent; - } - }; - - struct DetainedBlockExtentCompare { - bool operator()(const BlockExtent &lhs, - const BlockExtent &rhs) const { - // check for range overlap (lhs < rhs) - if (lhs.block_end <= rhs.block_start) { - return true; - } - return false; - } - }; - - typedef std::deque DetainedBlockExtentsPool; - typedef boost::intrusive::list DetainedBlockExtents; - typedef boost::intrusive::set< - DetainedBlockExtent, - boost::intrusive::compare, - boost::intrusive::key_of_value > - BlockExtentToDetainedBlockExtents; - - CephContext *m_cct; - - Mutex m_lock; - DetainedBlockExtentsPool m_detained_block_extent_pool; - DetainedBlockExtents m_free_detained_block_extents; - BlockExtentToDetainedBlockExtents m_detained_block_extents; - -}; - -} // namespace librbd - -#undef dout_subsys -#undef dout_prefix -#define dout_prefix *_dout - -#endif // CEPH_LIBRBD_IO_BLOCK_GUARD_H