]> git.ipfire.org Git - thirdparty/util-linux.git/commitdiff
lib/loopdev: introduce loopcxt_get_device_nr() helper
authorKarel Zak <kzak@redhat.com>
Thu, 16 Oct 2025 09:42:03 +0000 (11:42 +0200)
committerKarel Zak <kzak@redhat.com>
Tue, 21 Oct 2025 09:17:47 +0000 (11:17 +0200)
Add a new static helper function loopcxt_get_device_nr() to extract
the loop device number from the device path. This eliminates code
duplication in loopcxt_remove_device() and loopcxt_add_device().

The helper function supports both /dev/loop<N> and /dev/loop/<N>
formats and provides consistent error handling with debug logging.

Signed-off-by: Karel Zak <kzak@redhat.com>
lib/loopdev.c

index 5ef4394407958a7501f7f4fe58293563a92e7b33..7ba425e7cd17c39a69f76c92ac2baf5deb9b97c9 100644 (file)
@@ -1601,6 +1601,45 @@ int loopcxt_ioctl_blocksize(struct loopdev_cxt *lc, uint64_t blocksize)
        return 0;
 }
 
+/*
+ * @lc: context
+ * @nr: returns loop device number
+ *
+ * Extracts the loop device number from the device path.
+ * Supports both /dev/loop<N> and /dev/loop/<N> formats.
+ *
+ * Returns: 0 on success, <0 on error
+ */
+static int loopcxt_get_device_nr(struct loopdev_cxt *lc, int *nr)
+{
+       const char *p, *dev;
+       int rc = -EINVAL;
+
+       errno = 0;
+       if (!lc || !nr)
+               goto done;
+
+       dev = loopcxt_get_device(lc);
+       if (!dev)
+               goto done;
+
+       p = strrchr(dev, '/');
+       if (!p)
+               goto done;
+
+       if (sscanf(p, "/loop%d", nr) != 1 && sscanf(p, "/%d", nr) != 1)
+               goto done;
+
+       if (*nr < 0)
+               goto done;
+       rc = 0;
+done:
+       if (rc && !errno)
+               errno = -rc;
+       DBG(CXT, ul_debugobj(lc, "get_device_nr [nr=%d]", *nr));
+       return rc;
+}
+
 int loopcxt_detach_device(struct loopdev_cxt *lc)
 {
        int rc, fd = loopcxt_get_fd(lc);
@@ -1624,19 +1663,14 @@ int loopcxt_remove_device(struct loopdev_cxt *lc)
 {
        int rc = -EINVAL;
        int ctl, nr = -1;
-       const char *p, *dev = loopcxt_get_device(lc);
-
-       if (!dev)
-               goto done;
 
        if (!(lc->flags & LOOPDEV_FL_CONTROL)) {
                rc = -ENOSYS;
                goto done;
        }
 
-       p = strrchr(dev, '/');
-       if (!p || (sscanf(p, "/loop%d", &nr) != 1 && sscanf(p, "/%d", &nr) != 1)
-              || nr < 0)
+       rc = loopcxt_get_device_nr(lc, &nr);
+       if (rc)
                goto done;
 
        ctl = open(_PATH_DEV_LOOPCTL, O_RDWR|O_CLOEXEC);
@@ -1655,19 +1689,14 @@ int loopcxt_add_device(struct loopdev_cxt *lc)
 {
        int rc = -EINVAL;
        int ctl, nr = -1;
-       const char *p, *dev = loopcxt_get_device(lc);
-
-       if (!dev)
-               goto done;
 
        if (!(lc->flags & LOOPDEV_FL_CONTROL)) {
                rc = -ENOSYS;
                goto done;
        }
 
-       p = strrchr(dev, '/');
-       if (!p || (sscanf(p, "/loop%d", &nr) != 1 && sscanf(p, "/%d", &nr) != 1)
-              || nr < 0)
+       rc = loopcxt_get_device_nr(lc, &nr);
+       if (rc)
                goto done;
 
        ctl = open(_PATH_DEV_LOOPCTL, O_RDWR|O_CLOEXEC);