From a60cc5c2eeaad7ea5ea0c4a74cc4af5e2dc3f6c2 Mon Sep 17 00:00:00 2001 From: Ruediger Meier Date: Tue, 4 Apr 2017 16:29:58 +0200 Subject: [PATCH] util-linux-losetup-Add-support-for-setting-logical-blocksize.patch Signed-off-by: Ruediger Meier --- include/loopdev.h | 5 ++++- lib/loopdev.c | 20 ++++++++++++++++++++ sys-utils/losetup.c | 19 +++++++++++++++---- 3 files changed, 39 insertions(+), 5 deletions(-) diff --git a/include/loopdev.h b/include/loopdev.h index 953d2db..7c783bf 100644 --- a/include/loopdev.h +++ b/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_cxt *lc, uint64_t offset); 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); diff --git a/lib/loopdev.c b/lib/loopdev.c index fd4f166..b85e2ce 100644 --- a/lib/loopdev.c +++ b/lib/loopdev.c @@ -1115,6 +1115,26 @@ int loopcxt_set_backing_file(struct loopdev_cxt *lc, const char *filename) } /* + * @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 diff --git a/sys-utils/losetup.c b/sys-utils/losetup.c index 2218d3b..d8f1bfa 100644 --- a/sys-utils/losetup.c +++ b/sys-utils/losetup.c @@ -399,6 +399,7 @@ static void usage(FILE *out) fputs(USAGE_SEPARATOR, 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); @@ -448,7 +449,8 @@ static void warn_size(const char *filename, uint64_t size) 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; @@ -534,6 +536,8 @@ static int create_loop(struct loopdev_cxt *lc, 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))) { @@ -562,7 +566,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; @@ -572,7 +576,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", no_argument, NULL, 'a' }, @@ -585,6 +590,7 @@ int main(int argc, char **argv) { "associated", required_argument, NULL, 'j' }, { "json", no_argument, NULL, 'J' }, { "list", no_argument, NULL, 'l' }, + { "logical-blocksize", required_argument, NULL, OPT_BLOCKSIZE }, { "noheadings", no_argument, NULL, 'n' }, { "offset", required_argument, NULL, 'o' }, { "output", required_argument, NULL, 'O' }, @@ -658,6 +664,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; @@ -790,7 +800,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)); -- 1.8.5.6