File util-linux-loop-reuse-04.patch of Package util-linux.4768
From 74a4705a993ce475d95c1c20d0cc4eb740b0c933 Mon Sep 17 00:00:00 2001
From: Stanislav Brabec <sbrabec@suse.cz>
Date: Thu, 14 Jul 2016 15:29:09 +0200
Subject: [PATCH 4/20] 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>
---
include/loopdev.h | 8 +++++---
lib/ismounted.c | 2 +-
lib/loopdev.c | 26 +++++++++++++++++++-------
libmount/src/context_loopdev.c | 6 +++---
libmount/src/context_umount.c | 2 +-
libmount/src/tab.c | 2 +-
sys-utils/losetup.c | 8 ++++----
7 files changed, 34 insertions(+), 20 deletions(-)
Index: util-linux-2.28/include/loopdev.h
===================================================================
--- util-linux-2.28.orig/include/loopdev.h
+++ util-linux-2.28/include/loopdev.h
@@ -135,9 +135,9 @@ extern int loopdev_is_autoclear(const ch
extern char *loopdev_get_backing_file(const char *device);
extern int loopdev_is_used(const char *device, const char *filename,
- uint64_t offset, int flags);
+ uint64_t offset, uint64_t sizelimit, int flags);
extern char *loopdev_find_by_backing_file(const char *filename,
- uint64_t offset, int flags);
+ uint64_t offset, uint64_t sizelimit, int flags);
extern int loopcxt_find_unused(struct loopdev_cxt *lc);
extern int loopdev_delete(const char *device);
extern int loopdev_count_by_backing_file(const char *filename, char **loopdev);
@@ -189,12 +189,14 @@ extern int loopcxt_is_dio(struct loopdev
extern int loopcxt_is_partscan(struct loopdev_cxt *lc);
extern 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);
extern int loopcxt_is_used(struct loopdev_cxt *lc,
struct stat *st,
const char *backing_file,
uint64_t offset,
+ uint64_t sizelimit,
int flags);
#endif /* UTIL_LINUX_LOOPDEV_H */
Index: util-linux-2.28/lib/ismounted.c
===================================================================
--- util-linux-2.28.orig/lib/ismounted.c
+++ util-linux-2.28/lib/ismounted.c
@@ -85,7 +85,7 @@ static int check_mntent_file(const char
/* maybe the file is loopdev backing file */
if (file_dev
&& major(st_buf.st_rdev) == LOOPDEV_MAJOR
- && loopdev_is_used(mnt->mnt_fsname, file, 0, 0))
+ && loopdev_is_used(mnt->mnt_fsname, file, 0, 0, 0))
break;
#endif /* __linux__ */
#endif /* __GNU__ */
Index: util-linux-2.28/lib/loopdev.c
===================================================================
--- util-linux-2.28.orig/lib/loopdev.c
+++ util-linux-2.28/lib/loopdev.c
@@ -979,12 +979,15 @@ int loopcxt_is_dio(struct loopdev_cxt *l
* @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.
*/
@@ -992,6 +995,7 @@ int loopcxt_is_used(struct loopdev_cxt *
struct stat *st,
const char *backing_file,
uint64_t offset,
+ uint64_t sizelimit,
int flags)
{
ino_t ino;
@@ -1029,7 +1033,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;
}
@@ -1504,7 +1516,7 @@ char *loopdev_get_backing_file(const cha
* 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;
@@ -1520,7 +1532,7 @@ int loopdev_is_used(const char *device,
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;
@@ -1547,7 +1559,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;
@@ -1564,7 +1576,7 @@ int loopcxt_find_by_backing_file(struct
while ((rc = loopcxt_next(lc)) == 0) {
if (loopcxt_is_used(lc, hasst ? &st : NULL,
- filename, offset, flags))
+ filename, offset, sizelimit, flags))
break;
}
@@ -1575,7 +1587,7 @@ int loopcxt_find_by_backing_file(struct
/*
* 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;
@@ -1585,7 +1597,7 @@ char *loopdev_find_by_backing_file(const
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);
Index: util-linux-2.28/libmount/src/context_loopdev.c
===================================================================
--- util-linux-2.28.orig/libmount/src/context_loopdev.c
+++ util-linux-2.28/libmount/src/context_loopdev.c
@@ -119,13 +119,13 @@ is_mounted_same_loopfile(struct libmnt_c
rc = 0;
if (strncmp(src, "/dev/loop", 9) == 0) {
- rc = loopdev_is_used((char *) src, bf, offset, LOOPDEV_FL_OFFSET);
+ rc = loopdev_is_used((char *) src, bf, offset, 0, LOOPDEV_FL_OFFSET);
} else if (opts && (cxt->user_mountflags & MNT_MS_LOOP) &&
mnt_optstr_get_option(opts, "loop", &val, &len) == 0 && val) {
val = strndup(val, len);
- rc = loopdev_is_used((char *) val, bf, offset, LOOPDEV_FL_OFFSET);
+ rc = loopdev_is_used((char *) val, bf, offset, 0, LOOPDEV_FL_OFFSET);
free(val);
}
}
@@ -219,7 +219,7 @@ int mnt_context_setup_loopdev(struct lib
if (rc)
goto done_no_deinit;
if (backing_file && !(loopcxt_find_by_backing_file(&lc,
- backing_file, offset, LOOPDEV_FL_OFFSET))) {
+ backing_file, offset, sizelimit, LOOPDEV_FL_OFFSET))) {
DBG(CXT, ul_debugobj(cxt, "using existing loop device %s",
loopcxt_get_device(&lc)));
/* Once a loop is initialized RO, there is no way to safely
Index: util-linux-2.28/libmount/src/context_umount.c
===================================================================
--- util-linux-2.28.orig/libmount/src/context_umount.c
+++ util-linux-2.28/libmount/src/context_umount.c
@@ -328,7 +328,7 @@ static int is_associated_fs(const char *
return 0;
}
- return loopdev_is_used(devname, src, offset, flags);
+ return loopdev_is_used(devname, src, offset, 0, flags);
}
static int prepare_helper_from_options(struct libmnt_context *cxt,
Index: util-linux-2.28/libmount/src/tab.c
===================================================================
--- util-linux-2.28.orig/libmount/src/tab.c
+++ util-linux-2.28/libmount/src/tab.c
@@ -1563,7 +1563,7 @@ int mnt_table_is_fs_mounted(struct libmn
DBG(FS, ul_debugobj(fs, "checking for loop: src=%s", mnt_fs_get_srcpath(fs)));
#if __linux__
- if (!loopdev_is_used(mnt_fs_get_srcpath(fs), src, offset, flags))
+ if (!loopdev_is_used(mnt_fs_get_srcpath(fs), src, offset, 0, flags))
continue;
DBG(FS, ul_debugobj(fs, "used loop"));
Index: util-linux-2.28/sys-utils/losetup.c
===================================================================
--- util-linux-2.28.orig/sys-utils/losetup.c
+++ util-linux-2.28/sys-utils/losetup.c
@@ -178,10 +178,10 @@ static int show_all_loops(struct loopdev
int used;
const char *bf = cn_file ? cn_file : file;
- used = loopcxt_is_used(lc, st, bf, offset, flags);
+ used = loopcxt_is_used(lc, st, bf, offset, 0, flags);
if (!used && !cn_file) {
bf = cn_file = canonicalize_path(file);
- used = loopcxt_is_used(lc, st, bf, offset, flags);
+ used = loopcxt_is_used(lc, st, bf, offset, 0, flags);
}
if (!used)
continue;
@@ -344,10 +344,10 @@ static int show_table(struct loopdev_cxt
int used;
const char *bf = cn_file ? cn_file : file;
- used = loopcxt_is_used(lc, st, bf, offset, flags);
+ used = loopcxt_is_used(lc, st, bf, offset, 0, flags);
if (!used && !cn_file) {
bf = cn_file = canonicalize_path(file);
- used = loopcxt_is_used(lc, st, bf, offset, flags);
+ used = loopcxt_is_used(lc, st, bf, offset, 0, flags);
}
if (!used)
continue;