Commit 78e470c2 authored by Heinz Mauelshagen's avatar Heinz Mauelshagen Committed by Mike Snitzer

md: add raid4/5/6 journal mode switching API

Commit 2ded3703 ("md/r5cache: State machine for raid5-cache write
back mode") added support for "write-back" caching on the raid journal
device.

In order to allow the dm-raid target to switch between the available
"write-through" and "write-back" modes, provide a new
r5c_journal_mode_set() API.

Use the new API in existing r5c_journal_mode_store()
Signed-off-by: default avatarHeinz Mauelshagen <heinzm@redhat.com>
Acked-by: default avatarShaohua Li <shli@fb.com>
Signed-off-by: default avatarMike Snitzer <snitzer@redhat.com>
parent ff3af92b
......@@ -53,16 +53,6 @@
*/
#define R5L_POOL_SIZE 4
/*
* r5c journal modes of the array: write-back or write-through.
* write-through mode has identical behavior as existing log only
* implementation.
*/
enum r5c_journal_mode {
R5C_JOURNAL_MODE_WRITE_THROUGH = 0,
R5C_JOURNAL_MODE_WRITE_BACK = 1,
};
static char *r5c_journal_mode_str[] = {"write-through",
"write-back"};
/*
......@@ -2327,40 +2317,56 @@ static ssize_t r5c_journal_mode_show(struct mddev *mddev, char *page)
return ret;
}
static ssize_t r5c_journal_mode_store(struct mddev *mddev,
const char *page, size_t length)
/*
* Set journal cache mode on @mddev (external API initially needed by dm-raid).
*
* @mode as defined in 'enum r5c_journal_mode'.
*
*/
int r5c_journal_mode_set(struct mddev *mddev, int mode)
{
struct r5conf *conf = mddev->private;
struct r5l_log *log = conf->log;
int val = -1, i;
int len = length;
if (!log)
return -ENODEV;
if (len && page[len - 1] == '\n')
len -= 1;
for (i = 0; i < ARRAY_SIZE(r5c_journal_mode_str); i++)
if (strlen(r5c_journal_mode_str[i]) == len &&
strncmp(page, r5c_journal_mode_str[i], len) == 0) {
val = i;
break;
}
if (val < R5C_JOURNAL_MODE_WRITE_THROUGH ||
val > R5C_JOURNAL_MODE_WRITE_BACK)
if (mode < R5C_JOURNAL_MODE_WRITE_THROUGH ||
mode > R5C_JOURNAL_MODE_WRITE_BACK)
return -EINVAL;
if (raid5_calc_degraded(conf) > 0 &&
val == R5C_JOURNAL_MODE_WRITE_BACK)
mode == R5C_JOURNAL_MODE_WRITE_BACK)
return -EINVAL;
mddev_suspend(mddev);
conf->log->r5c_journal_mode = val;
conf->log->r5c_journal_mode = mode;
mddev_resume(mddev);
pr_debug("md/raid:%s: setting r5c cache mode to %d: %s\n",
mdname(mddev), val, r5c_journal_mode_str[val]);
return length;
mdname(mddev), mode, r5c_journal_mode_str[mode]);
return 0;
}
EXPORT_SYMBOL(r5c_journal_mode_set);
static ssize_t r5c_journal_mode_store(struct mddev *mddev,
const char *page, size_t length)
{
int mode = ARRAY_SIZE(r5c_journal_mode_str);
size_t len = length;
if (len < 2)
return -EINVAL;
if (page[len - 1] == '\n')
len--;
while (mode--)
if (strlen(r5c_journal_mode_str[mode]) == len &&
!strncmp(page, r5c_journal_mode_str[mode], len))
break;
return r5c_journal_mode_set(mddev, mode) ?: length;
}
struct md_sysfs_entry
......
......@@ -547,6 +547,16 @@ struct r5worker_group {
int stripes_cnt;
};
/*
* r5c journal modes of the array: write-back or write-through.
* write-through mode has identical behavior as existing log only
* implementation.
*/
enum r5c_journal_mode {
R5C_JOURNAL_MODE_WRITE_THROUGH = 0,
R5C_JOURNAL_MODE_WRITE_BACK = 1,
};
enum r5_cache_state {
R5_INACTIVE_BLOCKED, /* release of inactive stripes blocked,
* waiting for 25% to be free
......@@ -795,4 +805,5 @@ extern void r5c_check_cached_full_stripe(struct r5conf *conf);
extern struct md_sysfs_entry r5c_journal_mode;
extern void r5c_update_on_rdev_error(struct mddev *mddev);
extern bool r5c_big_stripe_cached(struct r5conf *conf, sector_t sect);
extern int r5c_journal_mode_set(struct mddev *mddev, int journal_mode);
#endif
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment