]> git.ipfire.org Git - thirdparty/util-linux.git/commitdiff
Add sizelimit to internal API
authorStanislav Brabec <sbrabec@suse.cz>
Thu, 14 Jul 2016 13:29:09 +0000 (15:29 +0200)
committerKarel Zak <kzak@redhat.com>
Wed, 3 Aug 2016 09:53:28 +0000 (11:53 +0200)
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
lib/ismounted.c
lib/loopdev.c
libmount/src/context_loopdev.c
libmount/src/context_umount.c
libmount/src/tab.c
sys-utils/losetup.c

index 18ca41fe836f0a89cd0df8010b7966825670fe4c..57fcc1b10de5e317e2b7c503a83f7491e90bec6f 100644 (file)
@@ -133,9 +133,9 @@ extern int loopdev_is_autoclear(const char *device);
 
 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);
@@ -186,12 +186,14 @@ extern int loopcxt_is_dio(struct loopdev_cxt *lc);
 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 f83be65e09b40aca71a3e444b3beb250e1cf016c..dd2d356c4e0dc1c3749d9f1dacd588b66bd05d3e 100644 (file)
@@ -85,7 +85,7 @@ static int check_mntent_file(const char *mtab_file, const char *file,
                        /* 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 73bbf8ba47aa82e2229342904b39bb07754d3cf3..2db80fc05a4c24766ec96379299e03d5d99d34a7 100644 (file)
@@ -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);
 
index 75306321901e45739523e45bad83f881d166285f..8a5706af094607c7fa81067e49f3f4b1f8ae0d1e 100644 (file)
@@ -119,13 +119,13 @@ is_mounted_same_loopfile(struct libmnt_context *cxt,
                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 libmnt_context *cxt)
        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(LOOP, 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 d003c5def31d6ed3f6539025ff03ef7c427f7121..28787dab148d44d0549353dc9c33f44b7be41845 100644 (file)
@@ -328,7 +328,7 @@ static int is_associated_fs(const char *devname, struct libmnt_fs *fs)
                        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 155c65ee36a6e2202c0a34a41048da149c3aaeca..341e5e343ef018b62080766239a3b3b30fa1ba59 100644 (file)
@@ -1555,7 +1555,7 @@ int mnt_table_is_fs_mounted(struct libmnt_table *tb, struct libmnt_fs *fstab_fs)
 
                        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 2ae6ace27f9d1cce79ac1facb5dbb7f830610afd..d9c75b9e0b80455f818f5ef48966cb26137a2429 100644 (file)
@@ -178,10 +178,10 @@ static int show_all_loops(struct loopdev_cxt *lc, const char *file,
                        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 *lc,
                                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;