提交 ea1c68b6 编写于 作者: M Mikulas Patocka 提交者: Yang Yingliang

dm writecache: return the exact table values that were set

stable inclusion
from linux-4.19.199
commit fb55695f41f6471ae8dff9e0a175fcec24fd3180

--------------------------------

commit 054bee16 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: NMikulas Patocka <mpatocka@redhat.com>
Cc: stable@vger.kernel.org # v4.18+
Signed-off-by: NMike Snitzer <snitzer@redhat.com>
Signed-off-by: NGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Signed-off-by: NYang Yingliang <yangyingliang@huawei.com>
上级 692fae40
...@@ -153,6 +153,7 @@ struct dm_writecache { ...@@ -153,6 +153,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;
...@@ -161,6 +162,10 @@ struct dm_writecache { ...@@ -161,6 +162,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;
...@@ -2045,6 +2050,7 @@ static int writecache_ctr(struct dm_target *ti, unsigned argc, char **argv) ...@@ -2045,6 +2050,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;
...@@ -2054,6 +2060,7 @@ static int writecache_ctr(struct dm_target *ti, unsigned argc, char **argv) ...@@ -2054,6 +2060,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--;
...@@ -2061,6 +2068,7 @@ static int writecache_ctr(struct dm_target *ti, unsigned argc, char **argv) ...@@ -2061,6 +2068,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--;
...@@ -2080,6 +2088,7 @@ static int writecache_ctr(struct dm_target *ti, unsigned argc, char **argv) ...@@ -2080,6 +2088,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)) {
...@@ -2275,7 +2284,6 @@ static void writecache_status(struct dm_target *ti, status_type_t type, ...@@ -2275,7 +2284,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:
...@@ -2287,7 +2295,7 @@ static void writecache_status(struct dm_target *ti, status_type_t type, ...@@ -2287,7 +2295,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;
...@@ -2303,26 +2311,18 @@ static void writecache_status(struct dm_target *ti, status_type_t type, ...@@ -2303,26 +2311,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;
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册