Package: flashcache Version: 3.1.3+git20150701-2 Followup-For: Bug #813037 User: a...@ubuntu.com Usertags: origin-ubuntu xenial ubuntu-patch
Hi, After discussions with upstream we have found a different existing mechamism to have target specific ioctl style calls. These are achieved via DM messages. The attached patch switches the kernel component to use DM messages to implement the whitelist/blacklist, and adds backwards compatibility for those to the flashcache_setioctl helper. Hope this is of use. -apw -- System Information: Debian Release: stretch/sid APT prefers xenial-updates APT policy: (500, 'xenial-updates'), (500, 'xenial-security'), (500, 'xenial'), (100, 'xenial-backports') Architecture: amd64 (x86_64) Foreign Architectures: i386 Kernel: Linux 4.3.0-5-generic (SMP w/4 CPU cores) Locale: LANG=en_GB.UTF-8, LC_CTYPE=en_GB.UTF-8 (charmap=UTF-8) Shell: /bin/sh linked to /bin/dash Init: systemd (via /run/systemd/system)
diff -Nru flashcache-3.1.3+git20150701/debian/patches/switch-from-ioctl-to-dm-target-messages.patch flashcache-3.1.3+git20150701/debian/patches/switch-from-ioctl-to-dm-target-messages.patch --- flashcache-3.1.3+git20150701/debian/patches/switch-from-ioctl-to-dm-target-messages.patch 1970-01-01 01:00:00.000000000 +0100 +++ flashcache-3.1.3+git20150701/debian/patches/switch-from-ioctl-to-dm-target-messages.patch 2016-01-29 21:26:43.000000000 +0000 @@ -0,0 +1,236 @@ +Description: switch from ioctl to dm target messages + Switch from ioctl to dm target messages for handling PID blacklist/whitelist + manipulation. +Author: Andy Whitcroft <a...@ubuntu.com> +Bug-Ubuntu: https://bugs.launchpad.net/bugs/1538618 + +Index: flashcache-3.1.3+git20150701/src/flashcache_conf.c +=================================================================== +--- flashcache-3.1.3+git20150701.orig/src/flashcache_conf.c ++++ flashcache-3.1.3+git20150701/src/flashcache_conf.c +@@ -1713,7 +1713,12 @@ static struct target_type flashcache_tar + .dtr = flashcache_dtr, + .map = flashcache_map, + .status = flashcache_status, ++#if LINUX_VERSION_CODE < KERNEL_VERSION(4,4,0) + .ioctl = flashcache_ioctl, ++#else ++ .prepare_ioctl = flashcache_prepare_ioctl, ++ .message = flashcache_message, ++#endif + .iterate_devices = flashcache_iterate_devices, + }; + +Index: flashcache-3.1.3+git20150701/src/flashcache_ioctl.c +=================================================================== +--- flashcache-3.1.3+git20150701.orig/src/flashcache_ioctl.c ++++ flashcache-3.1.3+git20150701/src/flashcache_ioctl.c +@@ -503,6 +503,82 @@ skip_sequential_io(struct cache_c *dmc, + * exit, for cases where the process dies after marking itself + * non-cacheable. + */ ++#if LINUX_VERSION_CODE >= KERNEL_VERSION(4,4,0) ++int ++flashcache_prepare_ioctl(struct dm_target *ti, ++ struct block_device **bdev, fmode_t *mode) ++{ ++ struct cache_c *dmc = (struct cache_c *) ti->private; ++ ++ *bdev = dmc->disk_dev->bdev; ++ ++ return 0; ++} ++ ++int ++flashcache_message(struct dm_target *ti, unsigned argc, char **argv) ++{ ++ struct cache_c *dmc = (struct cache_c *) ti->private; ++ int list; ++ long long upid; ++ pid_t pid = 0; ++ ++ /* ++ * whitelist|blacklist add|del <pid> ++ * whitelist|blacklist delall ++ */ ++ if (argc < 2) ++ return -EINVAL; ++ ++ /* Decode the primary command. */ ++ if (strcmp(argv[0], "whitelist") == 0) { ++ list = FLASHCACHE_WHITELIST; ++ } else if (strcmp(argv[0], "blacklist") == 0) { ++ list = FLASHCACHE_BLACKLIST; ++ } else { ++ return -EINVAL; ++ } ++ ++ /* Decode the sub-command. */ ++ if (strcmp(argv[1], "add") == 0) { ++ int rr; ++ if (argc != 3) ++ return -EINVAL; ++ ++ /* Decode the pid. */ ++ if (kstrtoull(argv[2], 10, &upid)) ++ return -EINVAL; ++ pid = (pid_t)upid; ++ ++ flashcache_add_pid(dmc, pid, list); ++ return 0; ++ ++ } else if (strcmp(argv[1], "del") == 0) { ++ if (argc != 3) ++ return -EINVAL; ++ ++ /* Decode the pid. */ ++ if (kstrtoull(argv[2], 10, &upid)) ++ return -EINVAL; ++ pid = (pid_t)upid; ++ ++ flashcache_del_pid(dmc, pid, list); ++ return 0; ++ ++ } else if (strcmp(argv[1], "delall") == 0) { ++ if (argc != 2) ++ return -EINVAL; ++ ++ flashcache_del_all_pids(dmc, list, 0); ++ return 0; ++ ++ } else { ++ return -EINVAL; ++ } ++} ++ ++#else ++ + int + #if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,27) + flashcache_ioctl(struct dm_target *ti, struct inode *inode, +@@ -561,3 +637,5 @@ flashcache_ioctl(struct dm_target *ti, u + } + + } ++ ++#endif +Index: flashcache-3.1.3+git20150701/src/flashcache_ioctl.h +=================================================================== +--- flashcache-3.1.3+git20150701.orig/src/flashcache_ioctl.h ++++ flashcache-3.1.3+git20150701/src/flashcache_ioctl.h +@@ -51,6 +51,11 @@ enum { + #define FLASHCACHEDELALLWHITELIST _IOW(FLASHCACHE_IOCTL, FLASHCACHEDELWHITELISTALL_CMD, pid_t) + + #ifdef __KERNEL__ ++#if LINUX_VERSION_CODE >= KERNEL_VERSION(4,4,0) ++int flashcache_message(struct dm_target *ti, unsigned argc, char **argv); ++int flashcache_prepare_ioctl(struct dm_target *ti, ++ struct block_device **bdev, fmode_t *mode); ++#else + #if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,27) + int flashcache_ioctl(struct dm_target *ti, struct inode *inode, + struct file *filp, unsigned int cmd, +@@ -59,6 +64,7 @@ int flashcache_ioctl(struct dm_target *t + int flashcache_ioctl(struct dm_target *ti, unsigned int cmd, + unsigned long arg); + #endif ++#endif + void flashcache_pid_expiry_all_locked(struct cache_c *dmc); + int flashcache_uncacheable(struct cache_c *dmc, struct bio *bio); + void seq_io_remove_from_lru(struct cache_c *dmc, struct sequential_io *seqio); +Index: flashcache-3.1.3+git20150701/src/utils/flashcache_setioctl.c +=================================================================== +--- flashcache-3.1.3+git20150701.orig/src/utils/flashcache_setioctl.c ++++ flashcache-3.1.3+git20150701/src/utils/flashcache_setioctl.c +@@ -33,6 +33,7 @@ + #include <sys/types.h> + #include <unistd.h> + #include <stdlib.h> ++#include <errno.h> + #include <linux/types.h> + #include <flashcache_ioctl.h> + +@@ -42,6 +43,55 @@ void usage(char *pname) + exit(1); + } + ++void dm_message(char *cachedev, char list, char action, pid_t pid) ++{ ++ char pidstr[32]; ++ ++ char *argv[] = { ++ "/sbin/dmsetup", ++ "message", ++ cachedev, ++ "0", ++ /* command */ NULL, ++ /* sub-command */ NULL, ++ /* pid */ NULL, ++ NULL, ++ }; ++ ++ switch (list) { ++ case 'w': ++ argv[4] = "whitelist"; ++ break; ++ case 'b': ++ argv[4] = "blacklist"; ++ break; ++ default: ++ return; ++ } ++ ++ switch (action) { ++ case 'a': ++ argv[5] = "add"; ++ break; ++ case 'r': ++ argv[5] = "del"; ++ break; ++ case 'c': ++ argv[5] = "delall"; ++ break; ++ } ++ ++ switch (action) { ++ case 'a': ++ case 'r': ++ snprintf(pidstr, sizeof(pidstr), "%lld", (long long)pid); ++ argv[6] = pidstr; ++ break; ++ } ++ ++ execv(argv[0], argv); ++} ++ + int + main(int argc, char **argv) + { +@@ -50,6 +100,7 @@ main(int argc, char **argv) + intmax_t pidmax; + char *tmp; + pid_t pid; ++ int err; + + while ((c = getopt(argc, argv, "carb:w:")) != -1) { + switch (c) { +@@ -125,11 +176,18 @@ main(int argc, char **argv) + break; + } + } ++ err = errno; + close(cache_fd); ++ /* ++ * Failed with an error indicating the ioctl was not appropriate for the device ++ * switch to using DM messages. ++ */ ++ if (result < 0 && err == ENOTTY) { ++ dm_message(cachedev, list, action, pid); ++ } + if (result < 0) { + fprintf(stderr, "ioctl failed on %s\n", cachedev); + exit(1); + } + return 0; + } +-