From 396a4f279eea91fc935823625e61670b81e823e7 Mon Sep 17 00:00:00 2001 From: Alessio Balsini Date: Tue, 27 Aug 2019 18:03:17 +0100 Subject: [PATCH] CreateSnapshot: reduce zero-filling for CoW images Instead of zero-filling the whole image, only clean the dm-snapshot metadata header of the CoW file. Zero-filling a large image may take a long time, and this is a safe, but not necessary operation if the operation is intended to prepare an initial CoW file that will be used with a dm-snapshot device. According to the Linux kernel code, only the first 32 bits of the CoW file is used to detect if the dm-snapshot device under creation will be at an initial state or the continuation of a previous dm-snapshot. CREATE_IMAGE_RESET_SNAP is a flag that reduces the zeroing of the image file to the first file chunk. Change-Id: Ibc9fb3b6d19666a92125c988687ff8dacfad47be Depends-On: I242e57a9a622fbb738bf82f8a260af1b13810069 Bug: 139378014 Test: manual, snapshot_test Signed-off-by: Alessio Balsini --- fs_mgr/libsnapshot/snapshot.cpp | 23 +++++++++++++++++++++-- 1 file changed, 21 insertions(+), 2 deletions(-) diff --git a/fs_mgr/libsnapshot/snapshot.cpp b/fs_mgr/libsnapshot/snapshot.cpp index 588941a4b..75528ab56 100644 --- a/fs_mgr/libsnapshot/snapshot.cpp +++ b/fs_mgr/libsnapshot/snapshot.cpp @@ -210,8 +210,27 @@ bool SnapshotManager::CreateSnapshot(LockedFile* lock, const std::string& name, } auto cow_name = GetCowName(name); - int cow_flags = IImageManager::CREATE_IMAGE_ZERO_FILL; - return images_->CreateBackingImage(cow_name, cow_size, cow_flags); + int cow_flags = IImageManager::CREATE_IMAGE_DEFAULT; + if (!images_->CreateBackingImage(cow_name, cow_size, cow_flags)) { + return false; + } + + // when the kernel creates a persistent dm-snapshot, it requires a CoW file + // to store the modifications. The kernel interface does not specify how + // the CoW is used, and there is no standard associated. + // By looking at the current implementation, the CoW file is treated as: + // - a _NEW_ snapshot if its first 32 bits are zero, so the newly created + // dm-snapshot device will look like a perfect copy of the origin device; + // - an _EXISTING_ snapshot if the first 32 bits are equal to a + // kernel-specified magic number and the CoW file metadata is set as valid, + // so it can be used to resume the last state of a snapshot device; + // - an _INVALID_ snapshot otherwise. + // To avoid zero-filling the whole CoW file when a new dm-snapshot is + // created, here we zero-fill only the first 32 bits. This is a temporary + // workaround that will be discussed again when the kernel API gets + // consolidated. + ssize_t dm_snap_magic_size = 4; // 32 bit + return images_->ZeroFillNewImage(cow_name, dm_snap_magic_size); } bool SnapshotManager::MapSnapshot(LockedFile* lock, const std::string& name,