]> git.ipfire.org Git - thirdparty/util-linux.git/commitdiff
lib/loopdev: set blocksize when create a new device
authorKarel Zak <kzak@redhat.com>
Tue, 22 Jan 2019 10:37:35 +0000 (11:37 +0100)
committerKarel Zak <kzak@redhat.com>
Tue, 22 Jan 2019 10:37:35 +0000 (11:37 +0100)
The partition scanner in kernel depends on blocksize. We need to set
the blocksize before we call LOOP_SET_STATUS64 (this ioctl triggers
the scanner).

This patch extends the internal API to save blocksize into loopdev
context to be usable later for loopcxt_setup_device().

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

index bbc0d3dd7984dff95cdcd7bd2b006d4c33fda0cc..0e3a7517a98513fa58fd3d35c3e45f66216a0dc5 100644 (file)
@@ -96,6 +96,7 @@ struct loopdev_cxt {
        char            *filename;      /* backing file for loopcxt_set_... */
        int             fd;             /* open(/dev/looo<N>) */
        int             mode;           /* fd mode O_{RDONLY,RDWR} */
+       uint64_t        blocksize;      /* used by loopcxt_setup_device() */
 
        int             flags;          /* LOOPDEV_FL_* flags */
        unsigned int    has_info:1;     /* .info contains data */
@@ -173,6 +174,7 @@ extern int loopcxt_ioctl_blocksize(struct loopdev_cxt *lc, uint64_t blocksize);
 
 int loopcxt_set_offset(struct loopdev_cxt *lc, uint64_t offset);
 int loopcxt_set_sizelimit(struct loopdev_cxt *lc, uint64_t sizelimit);
+int loopcxt_set_blocksize(struct loopdev_cxt *lc, uint64_t blocksize);
 int loopcxt_set_flags(struct loopdev_cxt *lc, uint32_t flags);
 int loopcxt_set_backing_file(struct loopdev_cxt *lc, const char *filename);
 
index 556c4df26df610a4e07dddaa1298452cfe08fe09..a57650cb5354fc5a798d41f906309747a3ec31ca 100644 (file)
@@ -96,6 +96,7 @@ int loopcxt_set_device(struct loopdev_cxt *lc, const char *device)
        }
        lc->fd = -1;
        lc->mode = 0;
+       lc->blocksize = 0;
        lc->has_info = 0;
        lc->info_failed = 0;
        *lc->device = '\0';
@@ -1106,6 +1107,22 @@ int loopcxt_set_sizelimit(struct loopdev_cxt *lc, uint64_t sizelimit)
        return 0;
 }
 
+/*
+ * The blocksize will be used by loopcxt_set_device(). For already exiting
+ * devices use  loopcxt_ioctl_blocksize().
+ *
+ * The setting is removed by loopcxt_set_device() loopcxt_next()!
+ */
+int loopcxt_set_blocksize(struct loopdev_cxt *lc, uint64_t blocksize)
+{
+       if (!lc)
+               return -EINVAL;
+       lc->blocksize = blocksize;
+
+       DBG(CXT, ul_debugobj(lc, "set blocksize=%jd", blocksize));
+       return 0;
+}
+
 /*
  * @lc: context
  * @flags: kernel LO_FLAGS_{READ_ONLY,USE_AOPS,AUTOCLEAR} flags
@@ -1331,6 +1348,12 @@ int loopcxt_setup_device(struct loopdev_cxt *lc)
 
        DBG(SETUP, ul_debugobj(lc, "LOOP_SET_FD: OK"));
 
+       if (lc->blocksize > 0
+           && (rc = loopcxt_ioctl_blocksize(lc, lc->blocksize)) < 0) {
+               errsv = -rc;
+               goto err;
+       }
+
        if (ioctl(dev_fd, LOOP_SET_STATUS64, &lc->info)) {
                rc = -errno;
                errsv = errno;