diff options
author | Stanislav Brabec | 2016-07-14 15:29:09 +0200 |
---|---|---|
committer | Karel Zak | 2016-08-03 11:53:28 +0200 |
commit | 74a4705a993ce475d95c1c20d0cc4eb740b0c933 (patch) | |
tree | 3d8f1ccfcd24f17448830c6f1977566917e31092 /lib/loopdev.c | |
parent | mount: Handle MNT_ERR_LOOPOVERLAP (diff) | |
download | kernel-qcow2-util-linux-74a4705a993ce475d95c1c20d0cc4eb740b0c933.tar.gz kernel-qcow2-util-linux-74a4705a993ce475d95c1c20d0cc4eb740b0c933.tar.xz kernel-qcow2-util-linux-74a4705a993ce475d95c1c20d0cc4eb740b0c933.zip |
Add sizelimit to internal API
Fully safe checks of loop device need to check sizelimit. To prevent need of two
nearly equal functions, introduce sizelimit parameter to several internal
functions:
loopdev_is_used()
loopdev_find_by_backing_file()
loopcxt_is_used()
loopcxt_find_by_backing_file()
If sizelimit is zero, fall back to the old behavior (ignoring of sizelimit).
Signed-off-by: Stanislav Brabec <sbrabec@suse.cz>
Diffstat (limited to 'lib/loopdev.c')
-rw-r--r-- | lib/loopdev.c | 26 |
1 files changed, 19 insertions, 7 deletions
diff --git a/lib/loopdev.c b/lib/loopdev.c index 73bbf8ba4..2db80fc05 100644 --- a/lib/loopdev.c +++ b/lib/loopdev.c @@ -980,12 +980,15 @@ int loopcxt_is_dio(struct loopdev_cxt *lc) * @backing_file: filename * @offset: offset * @flags: LOOPDEV_FL_OFFSET if @offset should not be ignored + * @flags: LOOPDEV_FL_SIZELIMIT if @sizelimit should not be ignored * * Returns 1 if the current @lc loopdev is associated with the given backing * file. Note that the preferred way is to use devno and inode number rather * than filename. The @backing_file filename is poor solution usable in case * that you don't have rights to call stat(). * + * LOOPDEV_FL_SIZELIMIT requires LOOPDEV_FL_OFFSET being set as well. + * * Don't forget that old kernels provide very restricted (in size) backing * filename by LOOP_GET_STAT64 ioctl only. */ @@ -993,6 +996,7 @@ int loopcxt_is_used(struct loopdev_cxt *lc, struct stat *st, const char *backing_file, uint64_t offset, + uint64_t sizelimit, int flags) { ino_t ino; @@ -1030,7 +1034,15 @@ found: if (flags & LOOPDEV_FL_OFFSET) { uint64_t off; - return loopcxt_get_offset(lc, &off) == 0 && off == offset; + int rc = loopcxt_get_offset(lc, &off) == 0 && off == offset; + + if (rc && flags & LOOPDEV_FL_SIZELIMIT) { + uint64_t sz; + + return loopcxt_get_sizelimit(lc, &sz) == 0 && sz == sizelimit; + } + else + return rc; } return 1; } @@ -1485,7 +1497,7 @@ char *loopdev_get_backing_file(const char *device) * Returns: TRUE/FALSE */ int loopdev_is_used(const char *device, const char *filename, - uint64_t offset, int flags) + uint64_t offset, uint64_t sizelimit, int flags) { struct loopdev_cxt lc; struct stat st; @@ -1501,7 +1513,7 @@ int loopdev_is_used(const char *device, const char *filename, return rc; rc = !stat(filename, &st); - rc = loopcxt_is_used(&lc, rc ? &st : NULL, filename, offset, flags); + rc = loopcxt_is_used(&lc, rc ? &st : NULL, filename, offset, sizelimit, flags); loopcxt_deinit(&lc); return rc; @@ -1528,7 +1540,7 @@ int loopdev_delete(const char *device) * Returns: 0 = success, < 0 error, 1 not found */ int loopcxt_find_by_backing_file(struct loopdev_cxt *lc, const char *filename, - uint64_t offset, int flags) + uint64_t offset, uint64_t sizelimit, int flags) { int rc, hasst; struct stat st; @@ -1545,7 +1557,7 @@ int loopcxt_find_by_backing_file(struct loopdev_cxt *lc, const char *filename, while ((rc = loopcxt_next(lc)) == 0) { if (loopcxt_is_used(lc, hasst ? &st : NULL, - filename, offset, flags)) + filename, offset, sizelimit, flags)) break; } @@ -1556,7 +1568,7 @@ int loopcxt_find_by_backing_file(struct loopdev_cxt *lc, const char *filename, /* * Returns allocated string with device name */ -char *loopdev_find_by_backing_file(const char *filename, uint64_t offset, int flags) +char *loopdev_find_by_backing_file(const char *filename, uint64_t offset, uint64_t sizelimit, int flags) { struct loopdev_cxt lc; char *res = NULL; @@ -1566,7 +1578,7 @@ char *loopdev_find_by_backing_file(const char *filename, uint64_t offset, int fl if (loopcxt_init(&lc, 0)) return NULL; - if (loopcxt_find_by_backing_file(&lc, filename, offset, flags) == 0) + if (loopcxt_find_by_backing_file(&lc, filename, offset, sizelimit, flags) == 0) res = loopcxt_strdup_device(&lc); loopcxt_deinit(&lc); |