pyocf: unique volume ops for each volume class

Signed-off-by: Adam Rutkowski <adam.j.rutkowski@intel.com>
This commit is contained in:
Adam Rutkowski 2022-03-12 15:19:22 +01:00
parent 7cb9523d8c
commit 2672f5460a
2 changed files with 96 additions and 94 deletions

View File

@ -66,10 +66,9 @@ class VolumeProperties(Structure):
("_caps", VolumeCaps), ("_caps", VolumeCaps),
("_io_ops", IoOps), ("_io_ops", IoOps),
("_deinit", c_char_p), ("_deinit", c_char_p),
("_ops", VolumeOps), ("_ops_", VolumeOps),
] ]
class VolumeIoPriv(Structure): class VolumeIoPriv(Structure):
_fields_ = [("_data", c_void_p), ("_offset", c_uint64)] _fields_ = [("_data", c_void_p), ("_offset", c_uint64)]
@ -80,55 +79,14 @@ VOLUME_POISON = 0x13
class Volume: class Volume:
_instances_ = weakref.WeakValueDictionary() _instances_ = weakref.WeakValueDictionary()
_uuid_ = weakref.WeakValueDictionary() _uuid_ = weakref.WeakValueDictionary()
_ops_ = {}
_props_ = {}
@classmethod @classmethod
def get_ops(cls): def get_ops(cls):
cls.ops = VolumeOps( if cls in Volume._ops_:
_submit_io=cls._submit_io, return Volume._ops_[cls]
_submit_flush=cls._submit_flush,
_submit_metadata=cls._submit_metadata,
_submit_discard=cls._submit_discard,
_submit_write_zeroes=cls._submit_write_zeroes,
_open=cls._open,
_close=cls._close,
_get_max_io_size=cls._get_max_io_size,
_get_length=cls._get_length,
)
return cls.ops
@classmethod
def get_io_ops(cls):
return IoOps(_set_data=cls._io_set_data, _get_data=cls._io_get_data)
@classmethod
def get_props(cls):
cls.props = VolumeProperties(
_name=str(cls.__name__).encode("ascii"),
_io_priv_size=sizeof(VolumeIoPriv),
_volume_priv_size=0,
_caps=VolumeCaps(_atomic_writes=0),
_ops=cls.get_ops(),
_io_ops=cls.get_io_ops(),
_deinit=0,
)
return cls.props
def get_copy(self):
raise NotImplementedError
@classmethod
def get_instance(cls, ref):
instance = cls._instances_[ref]
if instance is None:
print("tried to access {} but it's gone".format(ref))
return instance
@classmethod
def get_by_uuid(cls, uuid):
return cls._uuid_[uuid]
@staticmethod
@VolumeOps.SUBMIT_IO @VolumeOps.SUBMIT_IO
def _submit_io(io): def _submit_io(io):
io_structure = cast(io, POINTER(Io)) io_structure = cast(io, POINTER(Io))
@ -138,7 +96,6 @@ class Volume:
volume.submit_io(io_structure) volume.submit_io(io_structure)
@staticmethod
@VolumeOps.SUBMIT_FLUSH @VolumeOps.SUBMIT_FLUSH
def _submit_flush(flush): def _submit_flush(flush):
io_structure = cast(flush, POINTER(Io)) io_structure = cast(flush, POINTER(Io))
@ -148,12 +105,10 @@ class Volume:
volume.submit_flush(io_structure) volume.submit_flush(io_structure)
@staticmethod
@VolumeOps.SUBMIT_METADATA @VolumeOps.SUBMIT_METADATA
def _submit_metadata(meta): def _submit_metadata(meta):
raise NotImplementedError raise NotImplementedError
@staticmethod
@VolumeOps.SUBMIT_DISCARD @VolumeOps.SUBMIT_DISCARD
def _submit_discard(discard): def _submit_discard(discard):
io_structure = cast(discard, POINTER(Io)) io_structure = cast(discard, POINTER(Io))
@ -163,13 +118,11 @@ class Volume:
volume.submit_discard(io_structure) volume.submit_discard(io_structure)
@staticmethod
@VolumeOps.SUBMIT_WRITE_ZEROES @VolumeOps.SUBMIT_WRITE_ZEROES
def _submit_write_zeroes(write_zeroes): def _submit_write_zeroes(write_zeroes):
raise NotImplementedError raise NotImplementedError
@staticmethod @VolumeOps.OPEN
@CFUNCTYPE(c_int, c_void_p)
def _open(ref): def _open(ref):
uuid_ptr = cast( uuid_ptr = cast(
OcfLib.getInstance().ocf_volume_get_uuid(ref), POINTER(Uuid) OcfLib.getInstance().ocf_volume_get_uuid(ref), POINTER(Uuid)
@ -189,23 +142,69 @@ class Volume:
return volume.do_open() return volume.do_open()
@staticmethod
@VolumeOps.CLOSE @VolumeOps.CLOSE
def _close(ref): def _close(ref):
volume = Volume.get_instance(ref) volume = Volume.get_instance(ref)
volume.close() volume.close()
volume.opened = False volume.opened = False
@staticmethod
@VolumeOps.GET_MAX_IO_SIZE @VolumeOps.GET_MAX_IO_SIZE
def _get_max_io_size(ref): def _get_max_io_size(ref):
return Volume.get_instance(ref).get_max_io_size() return Volume.get_instance(ref).get_max_io_size()
@staticmethod
@VolumeOps.GET_LENGTH @VolumeOps.GET_LENGTH
def _get_length(ref): def _get_length(ref):
return Volume.get_instance(ref).get_length() return Volume.get_instance(ref).get_length()
Volume._ops_[cls] = VolumeOps(
_submit_io=_submit_io,
_submit_flush=_submit_flush,
_submit_metadata=_submit_metadata,
_submit_discard=_submit_discard,
_submit_write_zeroes=_submit_write_zeroes,
_open=_open,
_close=_close,
_get_max_io_size=_get_max_io_size,
_get_length=_get_length,
)
return Volume._ops_[cls]
@classmethod
def get_io_ops(cls):
return IoOps(_set_data=cls._io_set_data, _get_data=cls._io_get_data)
@classmethod
def get_props(cls):
if cls in Volume._props_:
return Volume._props_[cls]
Volume._props_[cls] = VolumeProperties(
_name=str(cls.__name__).encode("ascii"),
_io_priv_size=sizeof(VolumeIoPriv),
_volume_priv_size=0,
_caps=VolumeCaps(_atomic_writes=0),
_ops_=cls.get_ops(),
_io_ops=cls.get_io_ops(),
_deinit=0,
)
return Volume._props_[cls]
def get_copy(self):
raise NotImplementedError
@classmethod
def get_instance(cls, ref):
instance = cls._instances_[ref]
if instance is None:
print("tried to access {} but it's gone".format(ref))
return instance
@classmethod
def get_by_uuid(cls, uuid):
return cls._uuid_[uuid]
@staticmethod @staticmethod
@IoOps.SET_DATA @IoOps.SET_DATA
def _io_set_data(io, data, offset): def _io_set_data(io, data, offset):

View File

@ -21,6 +21,7 @@ from pyocf.types.cache import (
Backfill Backfill
) )
from pyocf.types.core import Core from pyocf.types.core import Core
from pyocf.types.ctx import OcfCtx
from pyocf.types.data import Data from pyocf.types.data import Data
from pyocf.types.io import IoDir from pyocf.types.io import IoDir
from pyocf.types.shared import OcfError, OcfCompletion, CacheLineSize, SeqCutOffPolicy from pyocf.types.shared import OcfError, OcfCompletion, CacheLineSize, SeqCutOffPolicy
@ -349,6 +350,8 @@ def test_start_cache_huge_device(pyocf_ctx_log_buffer, cls):
def submit_io(self, io): def submit_io(self, io):
io.contents._end(io, 0) io.contents._end(io, 0)
OcfCtx.get_default().register_volume_type(HugeDevice)
cache_device = HugeDevice() cache_device = HugeDevice()
with pytest.raises(OcfError, match="OCF_ERR_INVAL_CACHE_DEV"): with pytest.raises(OcfError, match="OCF_ERR_INVAL_CACHE_DEV"):