From e0724c40c0d13d23be248fd21e79fe6c398a3856 Mon Sep 17 00:00:00 2001 From: Yura Date: Thu, 16 Mar 2017 00:26:48 +0600 Subject: [PATCH] Fix kernel error --- flashcache-wt/src/Makefile | 3 -- src/Makefile | 6 +-- src/flashcache_conf.c | 5 +++ src/flashcache_ioctl.c | 78 +++++++++++++++++++++++++++++++++ src/flashcache_ioctl.h | 6 +++ src/flashcache_subr.c | 5 ++- src/utils/Makefile | 14 +++--- src/utils/flashcache_setioctl.c | 60 ++++++++++++++++++++++++- 8 files changed, 162 insertions(+), 15 deletions(-) diff --git a/flashcache-wt/src/Makefile b/flashcache-wt/src/Makefile index 5b8d19b..9c75a33 100644 --- a/flashcache-wt/src/Makefile +++ b/flashcache-wt/src/Makefile @@ -9,14 +9,11 @@ KERNEL_SOURCE_VERSION ?= $(shell uname -r) all: make -C $(KERNEL_TREE) M=$(PWD) modules - $(CC) $(UTILS_CFLAGS) -o utils/flashcache_wt_create utils/flashcache_wt_create.c install: all install -o root -g root -m 0755 -d /lib/modules/$(KERNEL_SOURCE_VERSION)/extra/flashcache/ install -o root -g root -m 0755 flashcache-wt.ko /lib/modules/$(KERNEL_SOURCE_VERSION)/extra/flashcache/ depmod -a - install -o root -g root -m 0755 utils/flashcache_wt_create /sbin/ clean: make -C $(KERNEL_TREE) M=$(PWD) clean - rm -f utils/flashcache_wt_create diff --git a/src/Makefile b/src/Makefile index 232e77b..f0316e5 100644 --- a/src/Makefile +++ b/src/Makefile @@ -1,4 +1,4 @@ -COMMIT_REV ?= $(shell git describe --always --abbrev=12) +COMMIT_REV ?= $(shell dpkg-query -W -f='$${Version}' flashcache-dkms | awk -F "-" '{print $$1}' | cut -d\: -f2) KERNEL_SOURCE_VERSION ?= $(shell uname -r) KERNEL_TREE ?= /lib/modules/$(KERNEL_SOURCE_VERSION)/build @@ -35,7 +35,7 @@ obj-m += flashcache.o flashcache-objs := flashcache_conf.o flashcache_main.o flashcache_subr.o flashcache_ioctl.o flashcache_procfs.o flashcache_reclaim.o flashcache_kcopy.o .PHONY: all -all: modules utils +all: modules .PHONY: modules modules: $(RHEL5_SETUP) @@ -60,7 +60,7 @@ ocf_install: make -C ocf install .PHONY: install -install: modules_install utils_install ocf_install +install: modules_install ocf_install .PHONY: clean clean: diff --git a/src/flashcache_conf.c b/src/flashcache_conf.c index 0ca05f7..5d9b555 100644 --- a/src/flashcache_conf.c +++ b/src/flashcache_conf.c @@ -1713,7 +1713,12 @@ static struct target_type flashcache_target = { .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, }; diff --git a/src/flashcache_ioctl.c b/src/flashcache_ioctl.c index 52ac56f..4fd1dcc 100644 --- a/src/flashcache_ioctl.c +++ b/src/flashcache_ioctl.c @@ -503,6 +503,82 @@ skip_sequential_io(struct cache_c *dmc, struct bio *bio) * 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 + * 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, unsigned int cmd, unsigned long arg) } } + +#endif diff --git a/src/flashcache_ioctl.h b/src/flashcache_ioctl.h index 105df6f..d3d7e25 100644 --- a/src/flashcache_ioctl.h +++ b/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 *ti, struct inode *inode, 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); diff --git a/src/flashcache_subr.c b/src/flashcache_subr.c index ef931d4..b2e2159 100644 --- a/src/flashcache_subr.c +++ b/src/flashcache_subr.c @@ -736,8 +736,11 @@ flashcache_bio_endio(struct bio *bio, int error, flashcache_record_latency(dmc, start_time); #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,24) bio_endio(bio, bio->bi_size, error); -#else +#elif LINUX_VERSION_CODE < KERNEL_VERSION(4,3,0) bio_endio(bio, error); +#else + bio->bi_error = error; + bio_endio(bio); #endif } diff --git a/src/utils/Makefile b/src/utils/Makefile index 234d447..2df6c7e 100644 --- a/src/utils/Makefile +++ b/src/utils/Makefile @@ -7,33 +7,33 @@ INSTALL_DIR = $(DESTDIR)/sbin/ all: $(PROGRAMS) get_agsize: get_agsize.o - $(CC) $^ -o $@ + $(LINK.o) $^ -o $@ -include get_agsize.d flashcache_create: flashcache_create.o - $(CC) $^ -o $@ + $(LINK.o) $^ -o $@ -include flashcache_create.d flashcache_destroy: flashcache_destroy.o - $(CC) $^ -o $@ + $(LINK.o) $^ -o $@ -include flashcache_destroy.d flashcache_load: flashcache_load.o - $(CC) $^ -o $@ + $(LINK.o) $^ -o $@ -include flashcache_load.d flashcache_setioctl: flashcache_setioctl.o - $(CC) $^ -o $@ + $(LINK.o) $^ -o $@ -include flashcache_setioctl.d %.o: %.c - $(CC) -c $(CFLAGS) $*.c -o $*.o - @$(CC) -MM $(CFLAGS) -MF $*.d -MT $*.o $*.c + $(COMPILE.c) $*.c -o $*.o + @$(COMPILE.c) -MM -MF $*.d -MT $*.o $*.c .PHONY: install install: $(PROGRAMS) diff --git a/src/utils/flashcache_setioctl.c b/src/utils/flashcache_setioctl.c index 44d5568..d2d7532 100644 --- a/src/utils/flashcache_setioctl.c +++ b/src/utils/flashcache_setioctl.c @@ -33,6 +33,7 @@ #include #include #include +#include #include #include @@ -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; } -