diff --git a/image_creator/disk.py b/image_creator/disk.py
index 2fc7a73d6d1a6448ed980cbc787c8c3a628faf5d..0b02d0504006dcb36afa4f064536dc57452ba015 100644
--- a/image_creator/disk.py
+++ b/image_creator/disk.py
@@ -18,7 +18,7 @@
 """Module hosting the Disk class."""
 
 from image_creator.util import get_command, try_fail_repeat, free_space, \
-    FatalError, image_info
+    FatalError, create_snapshot
 from image_creator.bundle_volume import BundleVolume
 from image_creator.image import Image
 
@@ -156,32 +156,18 @@ class Disk(object):
             self.out.warn("Snapshotting ignored for host bundling mode.")
             return self.file
 
-        mode = os.stat(self.file).st_mode
-        device = self.file if stat.S_ISBLK(mode) else self._losetup(self.file)
-        size = int(blockdev('--getsz', device))
-        virtual_size = (image_info(device)['virtual-size'] + 511) // 512
-
-        # If the virtual_size is bigger than the block device size, we need to
-        # create a bigger block device padded with zeros, otherwise QEMU will
-        # freeze if it tries to enlarge the underlying file.
-        if virtual_size > size:
-            zeros = virtual_size - size
-            tablefd, table = tempfile.mkstemp()
-            try:
-                try:
-                    os.write(tablefd, '0 %d linear %s 0\n' % (size, device))
-                    os.write(tablefd, '%d %d zero\n' % (size, zeros))
-                finally:
-                    os.close(tablefd)
-                padded = 'snf-image-creator-padded-%s' % uuid.uuid4().hex
-                dmsetup('create', padded, table)
-                self._add_cleanup(try_fail_repeat, dmsetup, 'remove', padded)
-            finally:
-                os.unlink(table)
-            device = "/dev/mapper/%s" % padded
-            size = virtual_size
-
         self.out.output("Snapshotting media source ...", False)
+
+        # Create a qcow2 snapshot for image files
+        if not stat.S_ISBLK(os.stat(self.file).st_mode):
+            snapshot = create_snapshot(self.file, self.tmp)
+            self._add_cleanup(os.unlink, snapshot)
+            self.out.success('done')
+            return snapshot
+
+        # Create a device-mapper snapshot for block devices
+        size = int(blockdev('--getsz', self.file))
+
         cowfd, cow = tempfile.mkstemp(dir=self.tmp)
         os.close(cowfd)
         self._add_cleanup(os.unlink, cow)
@@ -193,8 +179,8 @@ class Disk(object):
         tablefd, table = tempfile.mkstemp()
         try:
             try:
-                os.write(tablefd,
-                         "0 %d snapshot %s %s n 8\n" % (size, device, cowdev))
+                os.write(tablefd, "0 %d snapshot %s %s n 8\n" %
+                         (size, self.file, cowdev))
             finally:
                 os.close(tablefd)
 
diff --git a/image_creator/image.py b/image_creator/image.py
index 88074090b4bf20e5ce724d53068df409570197f0..da3777df927ee34c828b19044972863e2514ebe9 100644
--- a/image_creator/image.py
+++ b/image_creator/image.py
@@ -224,6 +224,7 @@ class Image(object):
             def __enter__(self):
                 return img.device if img.info['format'] == 'raw' else \
                     img.nbd.connect(readonly)
+
             def __exit__(self, exc_type, exc_value, traceback):
                 if img.info['format'] != 'raw':
                     img.nbd.disconnect()
diff --git a/image_creator/util.py b/image_creator/util.py
index 4d0fb34dff833bb22608c2396ed30e903589052b..dfae024be68350b58352b8c00e491ef9905e75d7 100644
--- a/image_creator/util.py
+++ b/image_creator/util.py
@@ -24,6 +24,7 @@ import time
 import os
 import re
 import json
+import tempfile
 from sh import qemu_img
 from sh import qemu_nbd
 from sh import modprobe
@@ -40,6 +41,16 @@ def image_info(image):
     return json.loads(str(info))
 
 
+def create_snapshot(source, target_dir):
+    """Returns a qcow2 snapshot of an image file"""
+
+    snapfd, snap = tempfile.mkstemp(prefix='snapshot-', dir=target_dir)
+    os.close(snapfd)
+    qemu_img('create', '-f', 'qcow2', '-o',
+             'backing_file=%s' % os.path.abspath(source), snap)
+    return snap
+
+
 def get_command(command):
     """Return a file system binary command"""
     def find_sbin_command(command, exception):