[bmap-tools] [PATCH 06/14] Fiemap: synchronize the file before invoking the ioctl

Artem Bityutskiy dedekind1 at gmail.com
Thu Sep 19 06:35:19 EDT 2013


From: Artem Bityutskiy <artem.bityutskiy at intel.com>

Early FIEMAP implementations had many bugs related to cached dirty data. And
this is why it is safer to synchronize the file before invoking FIEMAP for it.
Let's start using the 'FIEMAP_FLAG_SYNC' FIEMAP ioctl flag which does exactly
that.

Change-Id: I1698b88ed3978ffa632502ba72ad345ec8708ce0
Signed-off-by: Artem Bityutskiy <artem.bityutskiy at intel.com>
---
 TODO                |  3 +--
 bmaptools/Fiemap.py | 14 ++++++++++++--
 2 files changed, 13 insertions(+), 4 deletions(-)

diff --git a/TODO b/TODO
index c1d33ed..b1925bf 100644
--- a/TODO
+++ b/TODO
@@ -3,11 +3,10 @@ Current TODO list, any help with these is appreciated.
 3. In setup.py, fetch the version from 'bmaptool' file.
 4. Teach the 'make_a_release.sh' script to update the version and the
    changelog.
-5. Fsync before creating the bmap file (probably use FIEMAP_FLAG_SYNC flag)
 6. Write in the man page, docs, and may be --help that it is very important
    that the image is not changed while we create the bmep file, and after we
    have created it too.
 7. Verify that unmapped areas have all zeroes to guarantee integrity.
 8. Update the man pages
 9. Teach bmaptool to update the alternate GPT partition
-10. Document GPG singatures support and supported hash function types.
+10. Document GPG singatures support and supported hash function types
diff --git a/bmaptools/Fiemap.py b/bmaptools/Fiemap.py
index 9413358..b5f7c2c 100644
--- a/bmaptools/Fiemap.py
+++ b/bmaptools/Fiemap.py
@@ -39,6 +39,9 @@ _FIEMAP_EXTENT_FORMAT = "=QQQQQLLLL"
 _FIEMAP_EXTENT_SIZE = struct.calcsize(_FIEMAP_EXTENT_FORMAT)
 # The FIEMAP ioctl number
 _FIEMAP_IOCTL = 0xC020660B
+# This FIEMAP ioctl flag which instructs the kernel to sync the file before
+# reading the block map
+_FIEMAP_FLAG_SYNC = 0x00000001
 
 # Minimum buffer which is required for 'class Fiemap' to operate
 MIN_BUFFER_SIZE = _FIEMAP_SIZE + _FIEMAP_EXTENT_SIZE
@@ -68,6 +71,9 @@ class Fiemap:
         fiemap_extent' elements which will be used when invoking the FIEMAP
         ioctl. The larger is the buffer, the less times the FIEMAP ioctl will
         be invoked.
+
+        This class synchronizes the image file every time it invokes the FIEMAP
+        ioctl in order to work-around early FIEMAP implementation kernel bugs.
         """
 
         self._f_image_needs_close = False
@@ -148,9 +154,13 @@ class Fiemap:
             raise Error("bad block number %d, should be within [0, %d]"
                         % (block, self.blocks_cnt))
 
-        # Initialize the 'struct fiemap' part of the buffer
+        # Initialize the 'struct fiemap' part of the buffer. We use the
+        # '_FIEMAP_FLAG_SYNC' flag in order to make sure the file is
+        # synchronized. The reason for this is that early FIEMAP
+        # implementations had many bugs related to cached dirty data, and
+        # synchronizing the file is a necessary work-around.
         struct.pack_into(_FIEMAP_FORMAT, self._buf, 0, block * self.block_size,
-                         count * self.block_size, 0, 0,
+                         count * self.block_size, _FIEMAP_FLAG_SYNC, 0,
                          self._fiemap_extent_cnt, 0)
 
         try:
-- 
1.8.1.4




More information about the Bmap-tools mailing list