| From foo@baz Mon Sep 17 12:33:31 CEST 2018 |
| From: John Pittman <jpittman@redhat.com> |
| Date: Thu, 21 Jun 2018 17:35:33 -0400 |
| Subject: dm cache: only allow a single io_mode cache feature to be requested |
| |
| From: John Pittman <jpittman@redhat.com> |
| |
| [ Upstream commit af9313c32c0fa2a0ac3b113669273833d60cc9de ] |
| |
| More than one io_mode feature can be requested when creating a dm cache |
| device (as is: last one wins). The io_mode selections are incompatible |
| with one another, we should force them to be selected exclusively. Add |
| a counter to check for more than one io_mode selection. |
| |
| Fixes: 629d0a8a1a10 ("dm cache metadata: add "metadata2" feature") |
| Signed-off-by: John Pittman <jpittman@redhat.com> |
| Signed-off-by: Mike Snitzer <snitzer@redhat.com> |
| Signed-off-by: Sasha Levin <alexander.levin@microsoft.com> |
| Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> |
| --- |
| drivers/md/dm-cache-target.c | 19 +++++++++++++++---- |
| 1 file changed, 15 insertions(+), 4 deletions(-) |
| |
| --- a/drivers/md/dm-cache-target.c |
| +++ b/drivers/md/dm-cache-target.c |
| @@ -2330,7 +2330,7 @@ static int parse_features(struct cache_a |
| {0, 2, "Invalid number of cache feature arguments"}, |
| }; |
| |
| - int r; |
| + int r, mode_ctr = 0; |
| unsigned argc; |
| const char *arg; |
| struct cache_features *cf = &ca->features; |
| @@ -2344,14 +2344,20 @@ static int parse_features(struct cache_a |
| while (argc--) { |
| arg = dm_shift_arg(as); |
| |
| - if (!strcasecmp(arg, "writeback")) |
| + if (!strcasecmp(arg, "writeback")) { |
| cf->io_mode = CM_IO_WRITEBACK; |
| + mode_ctr++; |
| + } |
| |
| - else if (!strcasecmp(arg, "writethrough")) |
| + else if (!strcasecmp(arg, "writethrough")) { |
| cf->io_mode = CM_IO_WRITETHROUGH; |
| + mode_ctr++; |
| + } |
| |
| - else if (!strcasecmp(arg, "passthrough")) |
| + else if (!strcasecmp(arg, "passthrough")) { |
| cf->io_mode = CM_IO_PASSTHROUGH; |
| + mode_ctr++; |
| + } |
| |
| else if (!strcasecmp(arg, "metadata2")) |
| cf->metadata_version = 2; |
| @@ -2362,6 +2368,11 @@ static int parse_features(struct cache_a |
| } |
| } |
| |
| + if (mode_ctr > 1) { |
| + *error = "Duplicate cache io_mode features requested"; |
| + return -EINVAL; |
| + } |
| + |
| return 0; |
| } |
| |