Sign Up
Log In
Log In
or
Sign Up
Places
All Projects
Status Monitor
Collapse sidebar
SUSE:SLE-12:Update
util-linux-systemd.3352
util-linux-loop-reuse-12.patch
Overview
Repositories
Revisions
Requests
Users
Attributes
Meta
File util-linux-loop-reuse-12.patch of Package util-linux-systemd.3352
From dff7e1604680ee0118a04233ef365aebb869c9db Mon Sep 17 00:00:00 2001 From: Karel Zak <kzak@redhat.com> Date: Thu, 4 Aug 2016 11:48:26 +0200 Subject: [PATCH 12/20] libmount: one iteration to detect overlap and reuse loopdev The current code scans loopdevs to detect already used loop device and another scan to detect overlap. Let's use one scan only, for this purpose loopcxt_find_overlap() has been modified to return info (rc==2) about full size and offset match. Signed-off-by: Karel Zak <kzak@redhat.com> --- lib/loopdev.c | 22 ++++++++++++--- libmount/src/context_loopdev.c | 63 +++++++++++++++++++++--------------------- 2 files changed, 49 insertions(+), 36 deletions(-) Index: util-linux-2.25/lib/loopdev.c =================================================================== --- util-linux-2.25.orig/lib/loopdev.c +++ util-linux-2.25/lib/loopdev.c @@ -1566,7 +1566,7 @@ int loopcxt_find_by_backing_file(struct } /* - * Returns: 0 = success, < 0 error, 1 not found + * Returns: 0 = not found, < 0 error, 1 found, 2 found full size and offset match */ int loopcxt_find_overlap(struct loopdev_cxt *lc, const char *filename, uint64_t offset, uint64_t sizelimit) @@ -1590,7 +1590,7 @@ int loopcxt_find_overlap(struct loopdev_ filename, offset, sizelimit, 0); if (!rc) continue; /* unused */ - if (rc != 1) + if (rc < 0) break; /* error */ DBG(lc, loopdev_debug("found %s backed by %s", @@ -1609,15 +1609,29 @@ int loopcxt_find_overlap(struct loopdev_ break; } + /* full match */ + if (lc_sizelimit == sizelimit && lc_offset == offset) { + DBG(lc, loopdev_debug("overlapping loop device %s (full match)", + loopcxt_get_device(lc))); + rc = 2; + goto found; + } + + /* overlap */ if (lc_sizelimit != 0 && offset >= lc_offset + lc_sizelimit) continue; if (sizelimit != 0 && offset + sizelimit <= lc_offset) continue; + DBG(lc, loopdev_debug("overlapping loop device %s", loopcxt_get_device(lc))); - rc = 0; - break; + rc = 1; + goto found; } + + if (rc == 1) + rc = 0; /* not found */ +found: loopcxt_deinit_iterator(lc); return rc; } Index: util-linux-2.25/libmount/src/context_loopdev.c =================================================================== --- util-linux-2.25.orig/libmount/src/context_loopdev.c +++ util-linux-2.25/libmount/src/context_loopdev.c @@ -228,58 +228,54 @@ int mnt_context_setup_loopdev(struct lib if (rc) goto done_no_deinit; - rc = loopcxt_find_by_backing_file(&lc, - backing_file, offset, sizelimit, - LOOPDEV_FL_OFFSET | LOOPDEV_FL_SIZELIMIT); - if (rc < 0) + rc = loopcxt_find_overlap(&lc, backing_file, offset, sizelimit); + switch (rc) { + case 0: /* not found */ + DBG(CXT, ul_debugobj(cxt, "not found overlaping loopdev")); + loopcxt_deinit(&lc); + break; + + case 1: /* overlap */ + DBG(CXT, ul_debugobj(cxt, "overlaping %s detected", + loopcxt_get_device(&lc))); + rc = -MNT_ERR_LOOPOVERLAP; goto done; - if (rc == 0) { + + case 2: /* overlap -- full size and offset match (reuse) */ + { uint32_t lc_encrypt_type; - DBG(CXT, ul_debugobj(cxt, "using existing loop device %s", + DBG(CXT, ul_debugobj(cxt, "re-using existing loop device %s", loopcxt_get_device(&lc))); /* Once a loop is initialized RO, there is no - way to change its parameters. */ - if (loopcxt_is_readonly(&lc) && !(lo_flags & LO_FLAGS_READ_ONLY)) { + * way to change its parameters. */ + if (loopcxt_is_readonly(&lc) + && !(lo_flags & LO_FLAGS_READ_ONLY)) { + DBG(CXT, ul_debugobj(cxt, "%s is read-only", + loopcxt_get_device(&lc))); rc = -EROFS; goto done; } - /* This is no more supported, but check to be - * safe. */ - if (loopcxt_get_encrypt_type(&lc, &lc_encrypt_type)) { - DBG(CXT, ul_debugobj(cxt, "failed to get crypt type for device %s", - loopcxt_get_device(&lc))); - rc = -MNT_ERR_LOOPDEV; - goto done; - } - if (lc_encrypt_type != LO_CRYPT_NONE) { + /* This is no more supported, but check to be safe. */ + if (loopcxt_get_encrypt_type(&lc, &lc_encrypt_type) == 0 + && lc_encrypt_type != LO_CRYPT_NONE) { DBG(CXT, ul_debugobj(cxt, "encryption no longer supported for device %s", loopcxt_get_device(&lc))); rc = -MNT_ERR_LOOPOVERLAP; goto done; } + rc = 0; goto success; } - loopcxt_deinit(&lc); - /* No existing loop device matches. Now we need to - * check that no loop device overlaps our target range - * inside the backing file. */ - rc = loopcxt_init(&lc, 0); - if (rc) - goto done_no_deinit; - - rc = loopcxt_find_overlap(&lc, backing_file, offset, sizelimit); - if (rc < 0) - goto done; - if (rc == 0) { - rc = -MNT_ERR_LOOPOVERLAP; + default: /* error */ goto done; } loopcxt_deinit(&lc); } + DBG(CXT, ul_debugobj(cxt, "not found; create a new loop device")); rc = loopcxt_init(&lc, 0); if (rc) goto done_no_deinit; @@ -369,7 +365,11 @@ success: * otherwise it will be auto-cleared by kernel */ cxt->loopdev_fd = loopcxt_get_fd(&lc); - loopcxt_set_fd(&lc, -1, 0); + if (cxt->loopdev_fd < 0) { + DBG(CXT, ul_debugobj(cxt, "failed to get loopdev FD")); + rc = -errno; + } else + loopcxt_set_fd(&lc, -1, 0); } done: loopcxt_deinit(&lc);
Locations
Projects
Search
Status Monitor
Help
OpenBuildService.org
Documentation
API Documentation
Code of Conduct
Contact
Support
@OBShq
Terms
openSUSE Build Service is sponsored by
The Open Build Service is an
openSUSE project
.
Sign Up
Log In
Places
Places
All Projects
Status Monitor