From bcaeb70d80ff3f6f708beea6a70b70fb5ffa5154 Mon Sep 17 00:00:00 2001 From: Nikita Ioffe Date: Mon, 20 Apr 2020 17:38:17 +0100 Subject: [PATCH] PrepareZramBackingDevice: use loop_control.h loop_control.h already provides loop device management APIs that we need here. In addition, this change fixes a subtle race condition between uevented creating a loop device node in userspace and PrepareZramBackingDevice accessing it without waiting for it to be created. Test: device boots Test: adb reboot userspace Bug: 154500256 Change-Id: If80f18c8c337210030a6caf2aec6f7a47472b6fb Merged-In: If80f18c8c337210030a6caf2aec6f7a47472b6fb (cherry picked from commit c8313adf883f6c0d74718dbc4603adacd62ec16b) --- fs_mgr/fs_mgr.cpp | 39 ++++++++++++--------------------------- 1 file changed, 12 insertions(+), 27 deletions(-) diff --git a/fs_mgr/fs_mgr.cpp b/fs_mgr/fs_mgr.cpp index 0c2569d6a..d2daaa197 100644 --- a/fs_mgr/fs_mgr.cpp +++ b/fs_mgr/fs_mgr.cpp @@ -62,6 +62,7 @@ #include #include #include +#include #include #include #include @@ -105,6 +106,7 @@ using android::base::unique_fd; using android::dm::DeviceMapper; using android::dm::DmDeviceState; using android::dm::DmTargetLinear; +using android::dm::LoopControl; // Realistically, this file should be part of the android::fs_mgr namespace; using namespace android::fs_mgr; @@ -1908,19 +1910,6 @@ static bool PrepareZramDevice(const std::string& loop, off64_t size, const std:: return InstallZramDevice(bdev); } - // Get free loopback - unique_fd loop_fd(TEMP_FAILURE_RETRY(open("/dev/loop-control", O_RDWR | O_CLOEXEC))); - if (loop_fd.get() == -1) { - PERROR << "Cannot open loop-control"; - return false; - } - - int num = ioctl(loop_fd.get(), LOOP_CTL_GET_FREE); - if (num == -1) { - PERROR << "Cannot get free loop slot"; - return false; - } - // Prepare target path unique_fd target_fd(TEMP_FAILURE_RETRY(open(loop.c_str(), O_RDWR | O_CREAT | O_CLOEXEC, 0600))); if (target_fd.get() == -1) { @@ -1932,25 +1921,21 @@ static bool PrepareZramDevice(const std::string& loop, off64_t size, const std:: return false; } - // Connect loopback (device_fd) to target path (target_fd) - std::string device = android::base::StringPrintf("/dev/block/loop%d", num); - unique_fd device_fd(TEMP_FAILURE_RETRY(open(device.c_str(), O_RDWR | O_CLOEXEC))); - if (device_fd.get() == -1) { - PERROR << "Cannot open /dev/block/loop" << num; - return false; - } - - if (ioctl(device_fd.get(), LOOP_SET_FD, target_fd.get())) { - PERROR << "Cannot set loopback to target path"; + // Allocate loop device and attach it to file_path. + LoopControl loop_control; + std::string device; + if (!loop_control.Attach(target_fd.get(), 5s, &device)) { return false; } // set block size & direct IO - if (ioctl(device_fd.get(), LOOP_SET_BLOCK_SIZE, 4096)) { - PWARNING << "Cannot set 4KB blocksize to /dev/block/loop" << num; + unique_fd device_fd(TEMP_FAILURE_RETRY(open(device.c_str(), O_RDWR | O_CLOEXEC))); + if (device_fd.get() == -1) { + PERROR << "Cannot open " << device; + return false; } - if (ioctl(device_fd.get(), LOOP_SET_DIRECT_IO, 1)) { - PWARNING << "Cannot set direct_io to /dev/block/loop" << num; + if (!LoopControl::EnableDirectIo(device_fd.get())) { + return false; } return InstallZramDevice(device);