diff --git a/0204-losetup-support-ioctl-cmd-of-LOOP_SET_DIRECT_IO.patch b/0204-losetup-support-ioctl-cmd-of-LOOP_SET_DIRECT_IO.patch new file mode 100644 index 0000000000000000000000000000000000000000..b1c6260ace6062d30e7239e42a18334b01932318 --- /dev/null +++ b/0204-losetup-support-ioctl-cmd-of-LOOP_SET_DIRECT_IO.patch @@ -0,0 +1,160 @@ +From 8fda2e25dfcf51596c45c3ad3367e7780817448b Mon Sep 17 00:00:00 2001 +From: Ming Lei +Date: Tue, 17 Nov 2015 22:32:47 +0800 +Subject: [PATCH] losetup: support ioctl cmd of LOOP_SET_DIRECT_IO + +From v4.4, linux kernel starts to support direct I/O and +AIO to backing file for loop driver, so allow losetup to +enable the feature by using LOOP_SET_DIRECT_IO ioctl cmd. + +Signed-off-by: Ming Lei +Signed-off-by: Ferry Meng +--- + include/loopdev.h | 2 ++ + lib/loopdev.c | 18 ++++++++++++++++++ + sys-utils/losetup.c | 27 +++++++++++++++++++++++++-- + 3 files changed, 45 insertions(+), 2 deletions(-) + +diff --git a/include/loopdev.h b/include/loopdev.h +index eb328a0..5aee242 100644 +--- a/include/loopdev.h ++++ b/include/loopdev.h +@@ -23,6 +23,7 @@ + #define LOOP_GET_STATUS64 0x4C05 + /* #define LOOP_CHANGE_FD 0x4C06 */ + #define LOOP_SET_CAPACITY 0x4C07 ++#define LOOP_SET_DIRECT_IO 0x4C08 + + /* /dev/loop-control interface */ + #ifndef LOOP_CTL_ADD +@@ -165,6 +166,7 @@ extern int loopcxt_next(struct loopdev_cxt *lc); + extern int loopcxt_setup_device(struct loopdev_cxt *lc); + extern int loopcxt_delete_device(struct loopdev_cxt *lc); + extern int loopcxt_set_capacity(struct loopdev_cxt *lc); ++extern int loopcxt_set_dio(struct loopdev_cxt *lc, unsigned long use_dio); + + int loopcxt_set_offset(struct loopdev_cxt *lc, uint64_t offset); + int loopcxt_set_sizelimit(struct loopdev_cxt *lc, uint64_t sizelimit); +diff --git a/lib/loopdev.c b/lib/loopdev.c +index daf0a81..ac4ec15 100644 +--- a/lib/loopdev.c ++++ b/lib/loopdev.c +@@ -1288,6 +1288,24 @@ int loopcxt_set_capacity(struct loopdev_cxt *lc) + return 0; + } + ++int loopcxt_set_dio(struct loopdev_cxt *lc, unsigned long use_dio) ++{ ++ int fd = loopcxt_get_fd(lc); ++ ++ if (fd < 0) ++ return -EINVAL; ++ ++ /* Kernels prior to v4.4 don't support this ioctl */ ++ if (ioctl(fd, LOOP_SET_DIRECT_IO, use_dio) < 0) { ++ int rc = -errno; ++ DBG(lc, loopdev_debug("LOOP_SET_DIRECT_IO failed: %m")); ++ return rc; ++ } ++ ++ DBG(lc, loopdev_debug("direct io set")); ++ return 0; ++} ++ + int loopcxt_delete_device(struct loopdev_cxt *lc) + { + int fd = loopcxt_get_fd(lc); +diff --git a/sys-utils/losetup.c b/sys-utils/losetup.c +index 8df831b..6121979 100644 +--- a/sys-utils/losetup.c ++++ b/sys-utils/losetup.c +@@ -33,6 +33,7 @@ enum { + A_SHOW_ONE, /* print info about one device */ + A_FIND_FREE, /* find first unused */ + A_SET_CAPACITY, /* set device capacity */ ++ A_SET_DIRECT_IO, /* set accessing backing file by direct io */ + }; + + enum { +@@ -359,6 +360,7 @@ static void usage(FILE *out) + fputs(_(" --sizelimit device limited to bytes of the file\n"), out); + fputs(_(" -P, --partscan create partitioned loop device\n"), out); + fputs(_(" -r, --read-only setup read-only loop device\n"), out); ++ fputs(_(" --direct-io open backing file with O_DIRECT\n"), out); + fputs(_(" --show print device name after setup (with -f)\n"), out); + fputs(_(" -v, --verbose verbose mode\n"), out); + +@@ -404,10 +406,12 @@ int main(int argc, char **argv) + int res = 0, showdev = 0, lo_flags = 0; + char *outarg = NULL; + int list = 0; ++ unsigned long use_dio = 0, set_dio = 0; + + enum { + OPT_SIZELIMIT = CHAR_MAX + 1, +- OPT_SHOW ++ OPT_SHOW, ++ OPT_DIO + }; + static const struct option longopts[] = { + { "all", 0, 0, 'a' }, +@@ -425,6 +429,7 @@ int main(int argc, char **argv) + { "pass-fd", 1, 0, 'p' }, + { "partscan", 0, 0, 'P' }, + { "read-only", 0, 0, 'r' }, ++ { "direct-io", 1, 0, OPT_DIO }, + { "show", 0, 0, OPT_SHOW }, + { "verbose", 0, 0, 'v' }, + { "version", 0, 0, 'V' }, +@@ -508,6 +513,10 @@ int main(int argc, char **argv) + case OPT_SHOW: + showdev = 1; + break; ++ case OPT_DIO: ++ set_dio = 1; ++ use_dio = strtoul_or_err(optarg, _("failed to parse dio")); ++ break; + case 'v': + verbose = 1; + break; +@@ -559,8 +568,13 @@ int main(int argc, char **argv) + if (!act && optind + 1 == argc) { + /* + * losetup [--list] ++ * OR ++ * losetup --direct-io DIO + */ +- act = A_SHOW_ONE; ++ if (!set_dio) ++ act = A_SHOW_ONE; ++ else ++ act = A_SET_DIRECT_IO; + if (loopcxt_set_device(&lc, argv[optind])) + err(EXIT_FAILURE, _("%s: failed to use device"), + argv[optind]); +@@ -643,6 +657,8 @@ int main(int argc, char **argv) + if (showdev) + printf("%s\n", loopcxt_get_device(&lc)); + warn_size(file, sizelimit); ++ if (set_dio) ++ goto lo_set_dio; + } + break; + } +@@ -685,6 +701,13 @@ int main(int argc, char **argv) + warn(_("%s: set capacity failed"), + loopcxt_get_device(&lc)); + break; ++ case A_SET_DIRECT_IO: ++ lo_set_dio: ++ res = loopcxt_set_dio(&lc, use_dio); ++ if (res) ++ warn(_("%s: set direct io failed"), ++ loopcxt_get_device(&lc)); ++ break; + default: + usage(stderr); + break; +-- +2.43.5 + diff --git a/0205-losetup-support-list-direct-io.patch b/0205-losetup-support-list-direct-io.patch new file mode 100644 index 0000000000000000000000000000000000000000..993443524d760b7bf2a999ebd5ce211f8302fd0c --- /dev/null +++ b/0205-losetup-support-list-direct-io.patch @@ -0,0 +1,110 @@ +From 47f3dc4095f8ea973cd5612158856f59b20afccb Mon Sep 17 00:00:00 2001 +From: Ming Lei +Date: Tue, 17 Nov 2015 22:32:48 +0800 +Subject: [PATCH] losetup: support list direct io + +So that user can see if DIO is set for current loop device. + +Signed-off-by: Ming Lei +Signed-off-by: Ferry Meng +--- + include/loopdev.h | 2 ++ + lib/loopdev.c | 22 ++++++++++++++++++++++ + sys-utils/losetup.c | 7 +++++++ + 3 files changed, 31 insertions(+) + +diff --git a/include/loopdev.h b/include/loopdev.h +index 5aee242..3c714ae 100644 +--- a/include/loopdev.h ++++ b/include/loopdev.h +@@ -40,6 +40,7 @@ enum { + LO_FLAGS_USE_AOPS = 2, + LO_FLAGS_AUTOCLEAR = 4, /* kernel >= 2.6.25 */ + LO_FLAGS_PARTSCAN = 8, /* kernel >= 3.2 */ ++ LO_FLAGS_DIRECT_IO = 16, /* kernel >= 4.2 */ + }; + + #define LO_NAME_SIZE 64 +@@ -182,6 +183,7 @@ extern int loopcxt_get_encrypt_type(struct loopdev_cxt *lc, uint32_t *type); + extern const char *loopcxt_get_crypt_name(struct loopdev_cxt *lc); + extern int loopcxt_is_autoclear(struct loopdev_cxt *lc); + extern int loopcxt_is_readonly(struct loopdev_cxt *lc); ++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, +diff --git a/lib/loopdev.c b/lib/loopdev.c +index ac4ec15..32caa59 100644 +--- a/lib/loopdev.c ++++ b/lib/loopdev.c +@@ -943,6 +943,28 @@ int loopcxt_is_readonly(struct loopdev_cxt *lc) + return 0; + } + ++/* ++ * @lc: context ++ * ++ * Returns: 1 if the dio flags is set. ++ */ ++int loopcxt_is_dio(struct loopdev_cxt *lc) ++{ ++ struct sysfs_cxt *sysfs = loopcxt_get_sysfs(lc); ++ ++ if (sysfs) { ++ int fl; ++ if (sysfs_read_int(sysfs, "loop/dio", &fl) == 0) ++ return fl; ++ } ++ if (loopcxt_ioctl_enabled(lc)) { ++ struct loop_info64 *lo = loopcxt_get_info(lc); ++ if (lo) ++ return lo->lo_flags & LO_FLAGS_DIRECT_IO; ++ } ++ return 0; ++} ++ + /* + * @lc: context + * @st: backing file stat or NULL +diff --git a/sys-utils/losetup.c b/sys-utils/losetup.c +index 6121979..702674d 100644 +--- a/sys-utils/losetup.c ++++ b/sys-utils/losetup.c +@@ -47,6 +47,7 @@ enum { + COL_PARTSCAN, + COL_RO, + COL_SIZELIMIT, ++ COL_DIO, + }; + + struct tt *tt; +@@ -69,6 +70,7 @@ static struct colinfo infos[] = { + [COL_RO] = { "RO", 1, TT_FL_RIGHT, N_("read-only device")}, + [COL_SIZELIMIT] = { "SIZELIMIT", 5, TT_FL_RIGHT, N_("size limit of the file in bytes")}, + [COL_MAJMIN] = { "MAJ:MIN", 3, 0, N_("loop device major:minor number")}, ++ [COL_DIO] = { "DIO", 1, TT_FL_RIGHT, N_("access backing file with direct-io")}, + }; + + #define NCOLS ARRAY_SIZE(infos) +@@ -280,6 +282,10 @@ static int set_tt_data(struct loopdev_cxt *lc, struct tt_line *ln) + tt_line_set_data(ln, i, + xstrdup(loopcxt_is_readonly(lc) ? "1" : "0")); + break; ++ case COL_DIO: ++ tt_line_set_data(ln, i, ++ xstrdup(loopcxt_is_dio(lc) ? "1" : "0")); ++ break; + case COL_PARTSCAN: + tt_line_set_data(ln, i, + xstrdup(loopcxt_is_partscan(lc) ? "1" : "0")); +@@ -546,6 +552,7 @@ int main(int argc, char **argv) + columns[ncolumns++] = COL_AUTOCLR; + columns[ncolumns++] = COL_RO; + columns[ncolumns++] = COL_BACK_FILE; ++ columns[ncolumns++] = COL_DIO; + } + + if (act == A_FIND_FREE && optind < argc) { +-- +2.43.5 + diff --git a/0206-losetup-clean-up-direct-io.patch b/0206-losetup-clean-up-direct-io.patch new file mode 100644 index 0000000000000000000000000000000000000000..cc1c01151f16f1d21e28a146e002128e241dbd34 --- /dev/null +++ b/0206-losetup-clean-up-direct-io.patch @@ -0,0 +1,102 @@ +From 5a7e42450f135008c0968510925ace682c89c61f Mon Sep 17 00:00:00 2001 +From: Karel Zak +Date: Thu, 19 Nov 2015 11:57:05 +0100 +Subject: [PATCH] losetup: clean up --direct-io + +[backport note] +parse_switch func is different, so fix conflict with this helper. + +Signed-off-by: Karel Zak +Signed-off-by: Ferry Meng +--- + sys-utils/losetup.8 | 4 ++++ + sys-utils/losetup.c | 37 +++++++++++++++++++++++++++++++++---- + 2 files changed, 37 insertions(+), 4 deletions(-) + +diff --git a/sys-utils/losetup.8 b/sys-utils/losetup.8 +index 45c2201..cccfa9c 100644 +--- a/sys-utils/losetup.8 ++++ b/sys-utils/losetup.8 +@@ -86,6 +86,10 @@ operation does not return EBUSY error anymore if device is actively used by + system, but it is marked by autoclear flag and destroyed later. + .IP "\fB\-D, \-\-detach-all\fP" + detach all associated loop devices ++.IP \-\-direct\-io [ =on | off ] ++Enable or disable direct I/O for the backing file. The optional argument ++can be either \fBon\fR or \fBoff\fR. If the argument is omitted, it defaults ++to \fBon\fR. + .IP "\fB\-f, \-\-find\fP" + find the first unused loop device. If a + .I file +diff --git a/sys-utils/losetup.c b/sys-utils/losetup.c +index 702674d..8858849 100644 +--- a/sys-utils/losetup.c ++++ b/sys-utils/losetup.c +@@ -366,7 +366,7 @@ static void usage(FILE *out) + fputs(_(" --sizelimit device limited to bytes of the file\n"), out); + fputs(_(" -P, --partscan create partitioned loop device\n"), out); + fputs(_(" -r, --read-only setup read-only loop device\n"), out); +- fputs(_(" --direct-io open backing file with O_DIRECT\n"), out); ++ fputs(_(" --direct-io[=] open backing file with O_DIRECT\n"), out); + fputs(_(" --show print device name after setup (with -f)\n"), out); + fputs(_(" -v, --verbose verbose mode\n"), out); + +@@ -403,6 +403,33 @@ static void warn_size(const char *filename, uint64_t size) + filename); + } + ++int parse_switch_helper(const char *arg, const char *errmesg, ...) ++{ ++ const char *a, *b; ++ va_list ap; ++ ++ va_start(ap, errmesg); ++ do { ++ a = va_arg(ap, char *); ++ if (!a) ++ break; ++ b = va_arg(ap, char *); ++ if (!b) ++ break; ++ ++ if (strcmp(arg, a) == 0) { ++ va_end(ap); ++ return 1; ++ } else if (strcmp(arg, b) == 0) { ++ va_end(ap); ++ return 0; ++ } ++ } while (1); ++ va_end(ap); ++ ++ errx(STRTOXX_EXIT_CODE, "%s: '%s'", errmesg, arg); ++} ++ + int main(int argc, char **argv) + { + struct loopdev_cxt lc; +@@ -435,7 +462,7 @@ int main(int argc, char **argv) + { "pass-fd", 1, 0, 'p' }, + { "partscan", 0, 0, 'P' }, + { "read-only", 0, 0, 'r' }, +- { "direct-io", 1, 0, OPT_DIO }, ++ { "direct-io", 2, 0, OPT_DIO }, + { "show", 0, 0, OPT_SHOW }, + { "verbose", 0, 0, 'v' }, + { "version", 0, 0, 'V' }, +@@ -520,8 +547,10 @@ int main(int argc, char **argv) + showdev = 1; + break; + case OPT_DIO: +- set_dio = 1; +- use_dio = strtoul_or_err(optarg, _("failed to parse dio")); ++ use_dio = set_dio = 1; ++ if (optarg) { ++ use_dio = parse_switch_helper(optarg, _("argument error"), "on", "off", NULL); ++ } + break; + case 'v': + verbose = 1; +-- +2.43.5 + diff --git a/util-linux.spec b/util-linux.spec index 9162308fdd4d9fd5b4f79f7221ebc30ee51b897a..106d51503b81bdec922da72fed2a73a7654039f8 100644 --- a/util-linux.spec +++ b/util-linux.spec @@ -2,7 +2,7 @@ Summary: A collection of basic system utilities Name: util-linux Version: 2.23.2 -Release: 66%{?dist} +Release: 67%{?dist} License: GPLv2 and GPLv2+ and LGPLv2+ and BSD with advertising and Public Domain Group: System Environment/Base URL: http://en.wikipedia.org/wiki/Util-linux @@ -499,6 +499,10 @@ Patch201: 0201-chrt-use-SCHED_FLAG_RESET_ON_FORK-for-sched_setattr.patch # Anolis Patch202: 0202-libmount-add-support-for-MS_LAZYTIME.patch Patch203: 0203-mount-fix-lazytime-docs.patch +# add loop direct-io support +Patch204: 0204-losetup-support-ioctl-cmd-of-LOOP_SET_DIRECT_IO.patch +Patch205: 0205-losetup-support-list-direct-io.patch +Patch206: 0206-losetup-clean-up-direct-io.patch %description The util-linux package contains a large variety of low-level system @@ -1279,6 +1283,9 @@ fi %{_libdir}/pkgconfig/uuid.pc %changelog +* Wed Aug 21 2023 Ferry Meng 2.23.2-67 +- Add loop device direct-io support + * Wed Jun 07 2023 Ferry Meng 2.23.2-66 - Add lazytime/nolazytime vfs mount option recognization