diff --git a/src/flashcache_conf.c b/src/flashcache_conf.c index 0ca05f7..98b4b40 100644 --- a/src/flashcache_conf.c +++ b/src/flashcache_conf.c @@ -92,7 +92,7 @@ static void flashcache_sync_for_remove(struct cache_c *dmc); extern char *flashcache_sw_version; -#if LINUX_VERSION_CODE < KERNEL_VERSION(3,17,0) +#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,17,0) && ( RHEL_RELEASE_CODE < RHEL_RELEASE_VERSION(7,3) )) static int flashcache_wait_schedule(void *unused) { @@ -1225,7 +1225,7 @@ flashcache_ctr(struct dm_target *ti, unsigned int argc, char **argv) seq_io_move_to_lruhead(dmc, &dmc->seq_recent_ios[i]); } dmc->seq_io_tail = &dmc->seq_recent_ios[0]; -#if LINUX_VERSION_CODE < KERNEL_VERSION(3,17,0) +#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,17,0) && ( RHEL_RELEASE_CODE < RHEL_RELEASE_VERSION(7,3) )) (void)wait_on_bit_lock(&flashcache_control->synch_flags, FLASHCACHE_UPDATE_LIST, flashcache_wait_schedule, TASK_UNINTERRUPTIBLE); #else @@ -1235,7 +1235,7 @@ flashcache_ctr(struct dm_target *ti, unsigned int argc, char **argv) dmc->next_cache = cache_list_head; cache_list_head = dmc; clear_bit(FLASHCACHE_UPDATE_LIST, &flashcache_control->synch_flags); -#if LINUX_VERSION_CODE < KERNEL_VERSION(3,17,0) +#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,17,0) && ( RHEL_RELEASE_CODE < RHEL_RELEASE_VERSION(7,3) )) smp_mb__after_clear_bit(); #else smp_mb__after_atomic(); @@ -1437,7 +1437,7 @@ flashcache_dtr(struct dm_target *ti) DMINFO("cache queued jobs %d", nr_queued); flashcache_dtr_stats_print(dmc); -#if LINUX_VERSION_CODE < KERNEL_VERSION(3,17,0) +#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,17,0) && ( RHEL_RELEASE_CODE < RHEL_RELEASE_VERSION(7,3) )) (void)wait_on_bit_lock(&flashcache_control->synch_flags, FLASHCACHE_UPDATE_LIST, flashcache_wait_schedule, @@ -1456,7 +1456,7 @@ flashcache_dtr(struct dm_target *ti) nodepp = &((*nodepp)->next_cache); } clear_bit(FLASHCACHE_UPDATE_LIST, &flashcache_control->synch_flags); -#if LINUX_VERSION_CODE < KERNEL_VERSION(3,17,0) +#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,17,0) && ( RHEL_RELEASE_CODE < RHEL_RELEASE_VERSION(7,3) )) smp_mb__after_clear_bit(); #else smp_mb__after_atomic(); @@ -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) && ( RHEL_RELEASE_CODE < RHEL_RELEASE_VERSION(7,3) )) .ioctl = flashcache_ioctl, +#else + .prepare_ioctl = flashcache_prepare_ioctl, + .message = flashcache_message, +#endif .iterate_devices = flashcache_iterate_devices, }; @@ -1758,7 +1763,7 @@ flashcache_notify_reboot(struct notifier_block *this, { struct cache_c *dmc; -#if LINUX_VERSION_CODE < KERNEL_VERSION(3,17,0) +#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,17,0) && ( RHEL_RELEASE_CODE < RHEL_RELEASE_VERSION(7,3) )) (void)wait_on_bit_lock(&flashcache_control->synch_flags, FLASHCACHE_UPDATE_LIST, flashcache_wait_schedule, @@ -1779,7 +1784,7 @@ flashcache_notify_reboot(struct notifier_block *this, } } clear_bit(FLASHCACHE_UPDATE_LIST, &flashcache_control->synch_flags); -#if LINUX_VERSION_CODE < KERNEL_VERSION(3,17,0) +#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,17,0) && ( RHEL_RELEASE_CODE < RHEL_RELEASE_VERSION(7,3) )) smp_mb__after_clear_bit(); #else smp_mb__after_atomic(); diff --git a/src/flashcache_ioctl.c b/src/flashcache_ioctl.c index 52ac56f..ba1ec82 100644 --- a/src/flashcache_ioctl.c +++ b/src/flashcache_ioctl.c @@ -503,6 +503,81 @@ 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) || ( RHEL_RELEASE_CODE >= RHEL_RELEASE_VERSION(7,3) )) +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) { + 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 +636,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..76b1864 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) || ( RHEL_RELEASE_CODE >= RHEL_RELEASE_VERSION(7,3) )) +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_procfs.c b/src/flashcache_procfs.c index e7d4078..9c2ada3 100644 --- a/src/flashcache_procfs.c +++ b/src/flashcache_procfs.c @@ -70,7 +70,7 @@ static char *flashcache_cons_sysctl_devname(struct cache_c *dmc); #define FLASHCACHE_PROC_ROOTDIR_NAME "flashcache" static int -#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,17,0) +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,17,0) || ( RHEL_RELEASE_CODE >= RHEL_RELEASE_VERSION(7,3) )) flashcache_io_latency_init(struct ctl_table *table, int write, void __user *buffer, size_t *length, loff_t *ppos) @@ -103,7 +103,7 @@ flashcache_io_latency_init(ctl_table *table, int write, } static int -#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,17,0) +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,17,0) || ( RHEL_RELEASE_CODE >= RHEL_RELEASE_VERSION(7,3) )) flashcache_sync_sysctl(struct ctl_table *table, int write, void __user *buffer, size_t *length, loff_t *ppos) @@ -135,7 +135,7 @@ flashcache_sync_sysctl(ctl_table *table, int write, } static int -#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,17,0) +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,17,0) || ( RHEL_RELEASE_CODE >= RHEL_RELEASE_VERSION(7,3) )) flashcache_zerostats_sysctl(struct ctl_table *table, int write, void __user *buffer, size_t *length, loff_t *ppos) @@ -169,7 +169,7 @@ flashcache_zerostats_sysctl(ctl_table *table, int write, } static int -#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,17,0) +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,17,0) || ( RHEL_RELEASE_CODE >= RHEL_RELEASE_VERSION(7,3) )) flashcache_fallow_clean_speed_sysctl(struct ctl_table *table, int write, void __user *buffer, size_t *length, loff_t *ppos) @@ -200,7 +200,7 @@ flashcache_fallow_clean_speed_sysctl(ctl_table *table, int write, } static int -#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,17,0) +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,17,0) || ( RHEL_RELEASE_CODE >= RHEL_RELEASE_VERSION(7,3) )) flashcache_dirty_thresh_sysctl(struct ctl_table *table, int write, void __user *buffer, size_t *length, loff_t *ppos) @@ -234,7 +234,7 @@ flashcache_dirty_thresh_sysctl(ctl_table *table, int write, } static int -#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,17,0) +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,17,0) || ( RHEL_RELEASE_CODE >= RHEL_RELEASE_VERSION(7,3) )) flashcache_lru_hot_pct_sysctl(struct ctl_table *table, int write, void __user *buffer, size_t *length, loff_t *ppos) @@ -272,7 +272,7 @@ flashcache_lru_hot_pct_sysctl(ctl_table *table, int write, static struct flashcache_writeback_sysctl_table { struct ctl_table_header *sysctl_header; -#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,17,0) +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,17,0) || ( RHEL_RELEASE_CODE >= RHEL_RELEASE_VERSION(7,3) )) struct ctl_table vars[FLASHCACHE_NUM_WRITEBACK_SYSCTLS]; struct ctl_table dev[2]; struct ctl_table dir[2]; @@ -553,7 +553,7 @@ static struct flashcache_writeback_sysctl_table { static struct flashcache_writethrough_sysctl_table { struct ctl_table_header *sysctl_header; -#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,17,0) +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,17,0) || ( RHEL_RELEASE_CODE >= RHEL_RELEASE_VERSION(7,3) )) struct ctl_table vars[FLASHCACHE_NUM_WRITETHROUGH_SYSCTLS]; struct ctl_table dev[2]; struct ctl_table dir[2]; @@ -718,7 +718,7 @@ static struct flashcache_writethrough_sysctl_table { }; int * -#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,17,0) +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,17,0) || ( RHEL_RELEASE_CODE >= RHEL_RELEASE_VERSION(7,3) )) flashcache_find_sysctl_data(struct cache_c *dmc, struct ctl_table *vars) #else flashcache_find_sysctl_data(struct cache_c *dmc, ctl_table *vars) 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; } -