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 @@ ...@@ -53,16 +53,6 @@
*/ */
#define R5L_POOL_SIZE 4 #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", static char *r5c_journal_mode_str[] = {"write-through",
"write-back"}; "write-back"};
/* /*
...@@ -2327,40 +2317,56 @@ static ssize_t r5c_journal_mode_show(struct mddev *mddev, char *page) ...@@ -2327,40 +2317,56 @@ static ssize_t r5c_journal_mode_show(struct mddev *mddev, char *page)
return ret; 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 r5conf *conf = mddev->private;
struct r5l_log *log = conf->log; struct r5l_log *log = conf->log;
int val = -1, i;
int len = length;
if (!log) if (!log)
return -ENODEV; return -ENODEV;
if (len && page[len - 1] == '\n') if (mode < R5C_JOURNAL_MODE_WRITE_THROUGH ||
len -= 1; mode > R5C_JOURNAL_MODE_WRITE_BACK)
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)
return -EINVAL; return -EINVAL;
if (raid5_calc_degraded(conf) > 0 && if (raid5_calc_degraded(conf) > 0 &&
val == R5C_JOURNAL_MODE_WRITE_BACK) mode == R5C_JOURNAL_MODE_WRITE_BACK)
return -EINVAL; return -EINVAL;
mddev_suspend(mddev); mddev_suspend(mddev);
conf->log->r5c_journal_mode = val; conf->log->r5c_journal_mode = mode;
mddev_resume(mddev); mddev_resume(mddev);
pr_debug("md/raid:%s: setting r5c cache mode to %d: %s\n", pr_debug("md/raid:%s: setting r5c cache mode to %d: %s\n",
mdname(mddev), val, r5c_journal_mode_str[val]); mdname(mddev), mode, r5c_journal_mode_str[mode]);
return length; 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 struct md_sysfs_entry
......
...@@ -547,6 +547,16 @@ struct r5worker_group { ...@@ -547,6 +547,16 @@ struct r5worker_group {
int stripes_cnt; 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 { enum r5_cache_state {
R5_INACTIVE_BLOCKED, /* release of inactive stripes blocked, R5_INACTIVE_BLOCKED, /* release of inactive stripes blocked,
* waiting for 25% to be free * waiting for 25% to be free
...@@ -795,4 +805,5 @@ extern void r5c_check_cached_full_stripe(struct r5conf *conf); ...@@ -795,4 +805,5 @@ extern void r5c_check_cached_full_stripe(struct r5conf *conf);
extern struct md_sysfs_entry r5c_journal_mode; extern struct md_sysfs_entry r5c_journal_mode;
extern void r5c_update_on_rdev_error(struct mddev *mddev); extern void r5c_update_on_rdev_error(struct mddev *mddev);
extern bool r5c_big_stripe_cached(struct r5conf *conf, sector_t sect); 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 #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