import itertools
from bmaptools import BmapHelpers
+# Format string for 'struct fiemap'
+_FIEMAP_FORMAT = "=QQLLLL"
+# sizeof(struct fiemap)
+_FIEMAP_SIZE = struct.calcsize(_FIEMAP_FORMAT)
+# Format string for 'struct fiemap_extent'
+_FIEMAP_EXTENT_FORMAT = "=QQQQQLLLL"
+# sizeof(struct fiemap_extent)
+_FIEMAP_EXTENT_SIZE = struct.calcsize(_FIEMAP_EXTENT_FORMAT)
+# The FIEMAP ioctl number
+_FIEMAP_IOCTL = 0xC020660B
+
class Error(Exception):
""" A class for exceptions generated by this module. We currently support
only one type of exceptions, and we basically throw human-readable problem
# Prepare a 'struct fiemap' buffer which contains a single
# 'struct fiemap_extent' element.
- struct_fiemap_format = "=QQLLLL"
- struct_size = struct.calcsize(struct_fiemap_format)
- buf = struct.pack(struct_fiemap_format,
- block * self.block_size,
+ buf = struct.pack(_FIEMAP_FORMAT, block * self.block_size,
self.block_size, 0, 0, 1, 0)
- # sizeof(struct fiemap_extent) == 56
- buf += "\0"*56
+ buf += '\0' * _FIEMAP_EXTENT_SIZE
+
# Python strings are "immutable", meaning that python will pass a copy
# of the string to the ioctl, unless we turn it into an array.
buf = array.array('B', buf)
try:
- fcntl.ioctl(self._f_image, 0xC020660B, buf, 1)
+ fcntl.ioctl(self._f_image, _FIEMAP_IOCTL, buf, 1)
except IOError as err:
error_msg = "the FIBMAP ioctl failed for '%s': %s" \
% (self._image_path, err)
raise Error(error_msg)
- res = struct.unpack(struct_fiemap_format, buf[:struct_size])
+ res = struct.unpack(_FIEMAP_FORMAT, buf[:_FIEMAP_SIZE])
+
# res[3] is the 'fm_mapped_extents' field of 'struct fiemap'. If it
# contains zero, the block is not mapped, otherwise it is mapped.
return bool(res[3])