dm writecache: return the exact table values that were set
commit 054bee16163df023e2589db09fd27d81f7ad9e72 upstream. LVM doesn't like it when the target returns different values from what was set in the constructor. Fix dm-writecache so that the returned table values are exactly the same as requested values. Signed-off-by: Mikulas Patocka <mpatocka@redhat.com> Cc: stable@vger.kernel.org # v4.18+ Signed-off-by: Mike Snitzer <snitzer@redhat.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
This commit is contained in:
parent
8a85afc662
commit
d73c180e6a
|
@ -154,6 +154,7 @@ struct dm_writecache {
|
||||||
bool overwrote_committed:1;
|
bool overwrote_committed:1;
|
||||||
bool memory_vmapped:1;
|
bool memory_vmapped:1;
|
||||||
|
|
||||||
|
bool start_sector_set:1;
|
||||||
bool high_wm_percent_set:1;
|
bool high_wm_percent_set:1;
|
||||||
bool low_wm_percent_set:1;
|
bool low_wm_percent_set:1;
|
||||||
bool max_writeback_jobs_set:1;
|
bool max_writeback_jobs_set:1;
|
||||||
|
@ -162,6 +163,10 @@ struct dm_writecache {
|
||||||
bool writeback_fua_set:1;
|
bool writeback_fua_set:1;
|
||||||
bool flush_on_suspend:1;
|
bool flush_on_suspend:1;
|
||||||
|
|
||||||
|
unsigned high_wm_percent_value;
|
||||||
|
unsigned low_wm_percent_value;
|
||||||
|
unsigned autocommit_time_value;
|
||||||
|
|
||||||
unsigned writeback_all;
|
unsigned writeback_all;
|
||||||
struct workqueue_struct *writeback_wq;
|
struct workqueue_struct *writeback_wq;
|
||||||
struct work_struct writeback_work;
|
struct work_struct writeback_work;
|
||||||
|
@ -2069,6 +2074,7 @@ static int writecache_ctr(struct dm_target *ti, unsigned argc, char **argv)
|
||||||
if (sscanf(string, "%llu%c", &start_sector, &dummy) != 1)
|
if (sscanf(string, "%llu%c", &start_sector, &dummy) != 1)
|
||||||
goto invalid_optional;
|
goto invalid_optional;
|
||||||
wc->start_sector = start_sector;
|
wc->start_sector = start_sector;
|
||||||
|
wc->start_sector_set = true;
|
||||||
if (wc->start_sector != start_sector ||
|
if (wc->start_sector != start_sector ||
|
||||||
wc->start_sector >= wc->memory_map_size >> SECTOR_SHIFT)
|
wc->start_sector >= wc->memory_map_size >> SECTOR_SHIFT)
|
||||||
goto invalid_optional;
|
goto invalid_optional;
|
||||||
|
@ -2078,6 +2084,7 @@ static int writecache_ctr(struct dm_target *ti, unsigned argc, char **argv)
|
||||||
goto invalid_optional;
|
goto invalid_optional;
|
||||||
if (high_wm_percent < 0 || high_wm_percent > 100)
|
if (high_wm_percent < 0 || high_wm_percent > 100)
|
||||||
goto invalid_optional;
|
goto invalid_optional;
|
||||||
|
wc->high_wm_percent_value = high_wm_percent;
|
||||||
wc->high_wm_percent_set = true;
|
wc->high_wm_percent_set = true;
|
||||||
} else if (!strcasecmp(string, "low_watermark") && opt_params >= 1) {
|
} else if (!strcasecmp(string, "low_watermark") && opt_params >= 1) {
|
||||||
string = dm_shift_arg(&as), opt_params--;
|
string = dm_shift_arg(&as), opt_params--;
|
||||||
|
@ -2085,6 +2092,7 @@ static int writecache_ctr(struct dm_target *ti, unsigned argc, char **argv)
|
||||||
goto invalid_optional;
|
goto invalid_optional;
|
||||||
if (low_wm_percent < 0 || low_wm_percent > 100)
|
if (low_wm_percent < 0 || low_wm_percent > 100)
|
||||||
goto invalid_optional;
|
goto invalid_optional;
|
||||||
|
wc->low_wm_percent_value = low_wm_percent;
|
||||||
wc->low_wm_percent_set = true;
|
wc->low_wm_percent_set = true;
|
||||||
} else if (!strcasecmp(string, "writeback_jobs") && opt_params >= 1) {
|
} else if (!strcasecmp(string, "writeback_jobs") && opt_params >= 1) {
|
||||||
string = dm_shift_arg(&as), opt_params--;
|
string = dm_shift_arg(&as), opt_params--;
|
||||||
|
@ -2104,6 +2112,7 @@ static int writecache_ctr(struct dm_target *ti, unsigned argc, char **argv)
|
||||||
if (autocommit_msecs > 3600000)
|
if (autocommit_msecs > 3600000)
|
||||||
goto invalid_optional;
|
goto invalid_optional;
|
||||||
wc->autocommit_jiffies = msecs_to_jiffies(autocommit_msecs);
|
wc->autocommit_jiffies = msecs_to_jiffies(autocommit_msecs);
|
||||||
|
wc->autocommit_time_value = autocommit_msecs;
|
||||||
wc->autocommit_time_set = true;
|
wc->autocommit_time_set = true;
|
||||||
} else if (!strcasecmp(string, "fua")) {
|
} else if (!strcasecmp(string, "fua")) {
|
||||||
if (WC_MODE_PMEM(wc)) {
|
if (WC_MODE_PMEM(wc)) {
|
||||||
|
@ -2305,7 +2314,6 @@ static void writecache_status(struct dm_target *ti, status_type_t type,
|
||||||
struct dm_writecache *wc = ti->private;
|
struct dm_writecache *wc = ti->private;
|
||||||
unsigned extra_args;
|
unsigned extra_args;
|
||||||
unsigned sz = 0;
|
unsigned sz = 0;
|
||||||
uint64_t x;
|
|
||||||
|
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case STATUSTYPE_INFO:
|
case STATUSTYPE_INFO:
|
||||||
|
@ -2317,7 +2325,7 @@ static void writecache_status(struct dm_target *ti, status_type_t type,
|
||||||
DMEMIT("%c %s %s %u ", WC_MODE_PMEM(wc) ? 'p' : 's',
|
DMEMIT("%c %s %s %u ", WC_MODE_PMEM(wc) ? 'p' : 's',
|
||||||
wc->dev->name, wc->ssd_dev->name, wc->block_size);
|
wc->dev->name, wc->ssd_dev->name, wc->block_size);
|
||||||
extra_args = 0;
|
extra_args = 0;
|
||||||
if (wc->start_sector)
|
if (wc->start_sector_set)
|
||||||
extra_args += 2;
|
extra_args += 2;
|
||||||
if (wc->high_wm_percent_set)
|
if (wc->high_wm_percent_set)
|
||||||
extra_args += 2;
|
extra_args += 2;
|
||||||
|
@ -2333,26 +2341,18 @@ static void writecache_status(struct dm_target *ti, status_type_t type,
|
||||||
extra_args++;
|
extra_args++;
|
||||||
|
|
||||||
DMEMIT("%u", extra_args);
|
DMEMIT("%u", extra_args);
|
||||||
if (wc->start_sector)
|
if (wc->start_sector_set)
|
||||||
DMEMIT(" start_sector %llu", (unsigned long long)wc->start_sector);
|
DMEMIT(" start_sector %llu", (unsigned long long)wc->start_sector);
|
||||||
if (wc->high_wm_percent_set) {
|
if (wc->high_wm_percent_set)
|
||||||
x = (uint64_t)wc->freelist_high_watermark * 100;
|
DMEMIT(" high_watermark %u", wc->high_wm_percent_value);
|
||||||
x += wc->n_blocks / 2;
|
if (wc->low_wm_percent_set)
|
||||||
do_div(x, (size_t)wc->n_blocks);
|
DMEMIT(" low_watermark %u", wc->low_wm_percent_value);
|
||||||
DMEMIT(" high_watermark %u", 100 - (unsigned)x);
|
|
||||||
}
|
|
||||||
if (wc->low_wm_percent_set) {
|
|
||||||
x = (uint64_t)wc->freelist_low_watermark * 100;
|
|
||||||
x += wc->n_blocks / 2;
|
|
||||||
do_div(x, (size_t)wc->n_blocks);
|
|
||||||
DMEMIT(" low_watermark %u", 100 - (unsigned)x);
|
|
||||||
}
|
|
||||||
if (wc->max_writeback_jobs_set)
|
if (wc->max_writeback_jobs_set)
|
||||||
DMEMIT(" writeback_jobs %u", wc->max_writeback_jobs);
|
DMEMIT(" writeback_jobs %u", wc->max_writeback_jobs);
|
||||||
if (wc->autocommit_blocks_set)
|
if (wc->autocommit_blocks_set)
|
||||||
DMEMIT(" autocommit_blocks %u", wc->autocommit_blocks);
|
DMEMIT(" autocommit_blocks %u", wc->autocommit_blocks);
|
||||||
if (wc->autocommit_time_set)
|
if (wc->autocommit_time_set)
|
||||||
DMEMIT(" autocommit_time %u", jiffies_to_msecs(wc->autocommit_jiffies));
|
DMEMIT(" autocommit_time %u", wc->autocommit_time_value);
|
||||||
if (wc->writeback_fua_set)
|
if (wc->writeback_fua_set)
|
||||||
DMEMIT(" %sfua", wc->writeback_fua ? "" : "no");
|
DMEMIT(" %sfua", wc->writeback_fua ? "" : "no");
|
||||||
break;
|
break;
|
||||||
|
|
Loading…
Reference in New Issue