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),
("_io_ops", IoOps),
("_deinit", c_char_p),
("_ops", VolumeOps),
("_ops_", VolumeOps),
]
class VolumeIoPriv(Structure):
_fields_ = [("_data", c_void_p), ("_offset", c_uint64)]
@ -80,55 +79,14 @@ VOLUME_POISON = 0x13
class Volume:
_instances_ = weakref.WeakValueDictionary()
_uuid_ = weakref.WeakValueDictionary()
_ops_ = {}
_props_ = {}
@classmethod
def get_ops(cls):
cls.ops = VolumeOps(
_submit_io=cls._submit_io,
_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
if cls in Volume._ops_:
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):
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
def _submit_io(io):
io_structure = cast(io, POINTER(Io))
@ -138,7 +96,6 @@ class Volume:
volume.submit_io(io_structure)
@staticmethod
@VolumeOps.SUBMIT_FLUSH
def _submit_flush(flush):
io_structure = cast(flush, POINTER(Io))
@ -148,12 +105,10 @@ class Volume:
volume.submit_flush(io_structure)
@staticmethod
@VolumeOps.SUBMIT_METADATA
def _submit_metadata(meta):
raise NotImplementedError
@staticmethod
@VolumeOps.SUBMIT_DISCARD
def _submit_discard(discard):
io_structure = cast(discard, POINTER(Io))
@ -163,13 +118,11 @@ class Volume:
volume.submit_discard(io_structure)
@staticmethod
@VolumeOps.SUBMIT_WRITE_ZEROES
def _submit_write_zeroes(write_zeroes):
raise NotImplementedError
@staticmethod
@CFUNCTYPE(c_int, c_void_p)
@VolumeOps.OPEN
def _open(ref):
uuid_ptr = cast(
OcfLib.getInstance().ocf_volume_get_uuid(ref), POINTER(Uuid)
@ -189,23 +142,69 @@ class Volume:
return volume.do_open()
@staticmethod
@VolumeOps.CLOSE
def _close(ref):
volume = Volume.get_instance(ref)
volume.close()
volume.opened = False
@staticmethod
@VolumeOps.GET_MAX_IO_SIZE
def _get_max_io_size(ref):
return Volume.get_instance(ref).get_max_io_size()
@staticmethod
@VolumeOps.GET_LENGTH
def _get_length(ref):
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
@IoOps.SET_DATA
def _io_set_data(io, data, offset):

View File

@ -21,6 +21,7 @@ from pyocf.types.cache import (
Backfill
)
from pyocf.types.core import Core
from pyocf.types.ctx import OcfCtx
from pyocf.types.data import Data
from pyocf.types.io import IoDir
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):
io.contents._end(io, 0)
OcfCtx.get_default().register_volume_type(HugeDevice)
cache_device = HugeDevice()
with pytest.raises(OcfError, match="OCF_ERR_INVAL_CACHE_DEV"):