summaryrefslogtreecommitdiffstats
path: root/lib/loopdev.c
diff options
context:
space:
mode:
authorKarel Zak2016-08-04 11:48:26 +0200
committerKarel Zak2016-08-04 11:48:26 +0200
commitdff7e1604680ee0118a04233ef365aebb869c9db (patch)
tree8b50f04c4d3ae2ac60200f5a28ef8a853a890255 /lib/loopdev.c
parentlib/loopdev: cleanup sizelimit check (diff)
downloadkernel-qcow2-util-linux-dff7e1604680ee0118a04233ef365aebb869c9db.tar.gz
kernel-qcow2-util-linux-dff7e1604680ee0118a04233ef365aebb869c9db.tar.xz
kernel-qcow2-util-linux-dff7e1604680ee0118a04233ef365aebb869c9db.zip
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>
Diffstat (limited to 'lib/loopdev.c')
-rw-r--r--lib/loopdev.c22
1 files changed, 18 insertions, 4 deletions
diff --git a/lib/loopdev.c b/lib/loopdev.c
index cb925ae8e..21c8f4366 100644
--- a/lib/loopdev.c
+++ b/lib/loopdev.c
@@ -1566,7 +1566,7 @@ int loopcxt_find_by_backing_file(struct loopdev_cxt *lc, const char *filename,
}
/*
- * 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_cxt *lc, const char *filename,
filename, offset, sizelimit, 0);
if (!rc)
continue; /* unused */
- if (rc != 1)
+ if (rc < 0)
break; /* error */
DBG(CXT, ul_debugobj(lc, "found %s backed by %s",
@@ -1609,15 +1609,29 @@ int loopcxt_find_overlap(struct loopdev_cxt *lc, const char *filename,
break;
}
+ /* full match */
+ if (lc_sizelimit == sizelimit && lc_offset == offset) {
+ DBG(CXT, ul_debugobj(lc, "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(CXT, ul_debugobj(lc, "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;
}