diff --git a/drivers/md/dm-cache-target.c b/drivers/md/dm-cache-target.c index 097315a9bf0f..33dbc71b730f 100644 --- a/drivers/md/dm-cache-target.c +++ b/drivers/md/dm-cache-target.c @@ -16,6 +16,7 @@ #include #include #include +#include #include #include #include @@ -3311,42 +3312,46 @@ struct cblock_range { dm_cblock_t end; }; +static inline dm_cblock_t cblock_succ(dm_cblock_t b) +{ + return to_cblock(from_cblock(b) + 1); +} + /* * A cache block range can take two forms: * * i) A single cblock, eg. '3456' * ii) A begin and end cblock with a dash between, eg. 123-234 */ -static int parse_cblock_range(struct cache *cache, const char *str, +static int parse_cblock_range(struct cache *cache, char *str, struct cblock_range *result) { - char dummy; - uint64_t b, e; + char *blocknr = strsep(&str, "-"); + unsigned int b, e; int r; - /* - * Try and parse form (ii) first. - */ - r = sscanf(str, "%llu-%llu%c", &b, &e, &dummy); + r = kstrtouint(blocknr, 10, &b); + if (r) + goto bad; + + result->begin = to_cblock(b); + + if (str) { + blocknr = str; + + r = kstrtouint(blocknr, 10, &e); + if (r) + goto bad; - if (r == 2) { - result->begin = to_cblock(b); result->end = to_cblock(e); - return 0; + } else { + result->end = cblock_succ(result->begin); } - /* - * That didn't work, try form (i). - */ - r = sscanf(str, "%llu%c", &b, &dummy); + return 0; - if (r == 1) { - result->begin = to_cblock(b); - result->end = to_cblock(from_cblock(result->begin) + 1u); - return 0; - } - - DMERR("%s: invalid cblock range '%s'", cache_device_name(cache), str); +bad: + DMERR("%s: invalid cblock range '%s'", cache_device_name(cache), blocknr); return -EINVAL; } @@ -3377,11 +3382,6 @@ static int validate_cblock_range(struct cache *cache, struct cblock_range *range return 0; } -static inline dm_cblock_t cblock_succ(dm_cblock_t b) -{ - return to_cblock(from_cblock(b) + 1); -} - static int request_invalidation(struct cache *cache, struct cblock_range *range) { int r = 0; @@ -3405,7 +3405,7 @@ static int request_invalidation(struct cache *cache, struct cblock_range *range) } static int process_invalidate_cblocks_message(struct cache *cache, unsigned int count, - const char **cblock_ranges) + char **cblock_ranges) { int r = 0; unsigned int i; @@ -3460,7 +3460,7 @@ static int cache_message(struct dm_target *ti, unsigned int argc, char **argv, } if (!strcasecmp(argv[0], "invalidate_cblocks")) - return process_invalidate_cblocks_message(cache, argc - 1, (const char **) argv + 1); + return process_invalidate_cblocks_message(cache, argc - 1, argv + 1); if (argc != 2) return -EINVAL;