Index: util-linux-2.29/include/loopdev.h =================================================================== --- util-linux-2.29.orig/include/loopdev.h +++ util-linux-2.29/include/loopdev.h @@ -41,6 +41,7 @@ enum { LO_FLAGS_AUTOCLEAR = 4, /* kernel >= 2.6.25 */ LO_FLAGS_PARTSCAN = 8, /* kernel >= 3.2 */ LO_FLAGS_DIRECT_IO = 16, /* kernel >= 4.2 */ + LO_FLAGS_BLOCKSIZE = 32, /* Tentative */ }; #define LO_NAME_SIZE 64 @@ -120,7 +121,8 @@ enum { LOOPDEV_FL_NOIOCTL = (1 << 6), LOOPDEV_FL_DEVSUBDIR = (1 << 7), LOOPDEV_FL_CONTROL = (1 << 8), /* system with /dev/loop-control */ - LOOPDEV_FL_SIZELIMIT = (1 << 9) + LOOPDEV_FL_SIZELIMIT = (1 << 9), + LOOPDEV_FL_BLOCKSIZE = (1 << 10) }; /* @@ -173,6 +175,7 @@ int loopcxt_set_offset(struct loopdev_cx int loopcxt_set_sizelimit(struct loopdev_cxt *lc, uint64_t sizelimit); int loopcxt_set_flags(struct loopdev_cxt *lc, uint32_t flags); int loopcxt_set_backing_file(struct loopdev_cxt *lc, const char *filename); +int loopcxt_set_blocksize(struct loopdev_cxt *lc, uint64_t blocksize); extern char *loopcxt_get_backing_file(struct loopdev_cxt *lc); extern int loopcxt_get_backing_devno(struct loopdev_cxt *lc, dev_t *devno); Index: util-linux-2.29/lib/loopdev.c =================================================================== --- util-linux-2.29.orig/lib/loopdev.c +++ util-linux-2.29/lib/loopdev.c @@ -1115,6 +1115,26 @@ int loopcxt_set_backing_file(struct loop } /* + * @lc: context + * @blocksize: logical blocksize for the device + * + * The setting is removed by loopcxt_set_device() loopcxt_next()! + * + * Returns: 0 on success, <0 on error. + */ +int loopcxt_set_blocksize(struct loopdev_cxt *lc, uint64_t blocksize) +{ + if (!lc) + return -EINVAL; + + lc->info.lo_init[0] = blocksize; + lc->info.lo_flags |= LO_FLAGS_BLOCKSIZE; + + DBG(CXT, ul_debugobj(lc, "set blocksize=%llu", (long long unsigned int)lc->info.lo_init[0])); + return 0; +} + +/* * In kernels prior to v3.9, if the offset or sizelimit options * are used, the block device's size won't be synced automatically. * blockdev --getsize64 and filesystems will use the backing Index: util-linux-2.29/sys-utils/losetup.c =================================================================== --- util-linux-2.29.orig/sys-utils/losetup.c +++ util-linux-2.29/sys-utils/losetup.c @@ -398,6 +398,7 @@ static void usage(FILE *out) fputs(_(" -o, --offset start at offset into file\n"), out); fputs(_(" --sizelimit device is limited to bytes of the file\n"), out); + fputs(_(" --logical-blocksize set the logical block size to \n"), out); fputs(_(" -P, --partscan create a partitioned loop device\n"), out); fputs(_(" -r, --read-only set up a read-only loop device\n"), out); fputs(_(" --direct-io[=] open backing file with O_DIRECT\n"), out); @@ -447,7 +448,8 @@ static void warn_size(const char *filena static int create_loop(struct loopdev_cxt *lc, int nooverlap, int lo_flags, int flags, - const char *file, uint64_t offset, uint64_t sizelimit) + const char *file, uint64_t offset, uint64_t sizelimit, + uint64_t blocksize) { int hasdev = loopcxt_has_device(lc); int rc = 0; @@ -533,6 +535,8 @@ static int create_loop(struct loopdev_cx loopcxt_set_offset(lc, offset); if (flags & LOOPDEV_FL_SIZELIMIT) loopcxt_set_sizelimit(lc, sizelimit); + if (flags & LOOPDEV_FL_BLOCKSIZE) + loopcxt_set_blocksize(lc, blocksize); if (lo_flags) loopcxt_set_flags(lc, lo_flags); if ((rc = loopcxt_set_backing_file(lc, file))) { @@ -561,7 +565,7 @@ int main(int argc, char **argv) struct loopdev_cxt lc; int act = 0, flags = 0, no_overlap = 0, c; char *file = NULL; - uint64_t offset = 0, sizelimit = 0; + uint64_t offset = 0, sizelimit = 0, blocksize = 0; int res = 0, showdev = 0, lo_flags = 0; char *outarg = NULL; int list = 0; @@ -571,7 +575,8 @@ int main(int argc, char **argv) OPT_SIZELIMIT = CHAR_MAX + 1, OPT_SHOW, OPT_RAW, - OPT_DIO + OPT_DIO, + OPT_BLOCKSIZE, }; static const struct option longopts[] = { { "all", 0, 0, 'a' }, @@ -584,6 +589,7 @@ int main(int argc, char **argv) { "associated", 1, 0, 'j' }, { "json", 0, 0, 'J' }, { "list", 0, 0, 'l' }, + { "logical-blocksize", 1, 0, OPT_BLOCKSIZE }, { "noheadings", 0, 0, 'n' }, { "offset", 1, 0, 'o' }, { "output", 1, 0, 'O' }, @@ -657,6 +663,10 @@ int main(int argc, char **argv) act = A_SHOW; file = optarg; break; + case OPT_BLOCKSIZE: + blocksize = strtosize_or_err(optarg, _("failed to parse logical block size")); + flags |= LOOPDEV_FL_BLOCKSIZE; + break; case 'l': list = 1; break; @@ -789,7 +799,8 @@ int main(int argc, char **argv) switch (act) { case A_CREATE: - res = create_loop(&lc, no_overlap, lo_flags, flags, file, offset, sizelimit); + res = create_loop(&lc, no_overlap, lo_flags, flags, file, offset, + sizelimit, blocksize); if (res == 0) { if (showdev) printf("%s\n", loopcxt_get_device(&lc));