Commit 2c7da14b authored by Song Liu's avatar Song Liu Committed by Shaohua Li

md/r5cache: sysfs entry journal_mode

With write cache, journal_mode is the knob to switch between
write-back and write-through.

Below is an example:

root@virt-test:~/# cat /sys/block/md0/md/journal_mode
[write-through] write-back
root@virt-test:~/# echo write-back > /sys/block/md0/md/journal_mode
root@virt-test:~/# cat /sys/block/md0/md/journal_mode
write-through [write-back]
Signed-off-by: default avatarSong Liu <songliubraving@fb.com>
Signed-off-by: default avatarShaohua Li <shli@fb.com>
parent a39f7afd
...@@ -60,6 +60,8 @@ enum r5c_journal_mode { ...@@ -60,6 +60,8 @@ enum r5c_journal_mode {
R5C_JOURNAL_MODE_WRITE_BACK = 1, R5C_JOURNAL_MODE_WRITE_BACK = 1,
}; };
static char *r5c_journal_mode_str[] = {"write-through",
"write-back"};
/* /*
* raid5 cache state machine * raid5 cache state machine
* *
...@@ -1617,6 +1619,69 @@ static void r5l_write_super(struct r5l_log *log, sector_t cp) ...@@ -1617,6 +1619,69 @@ static void r5l_write_super(struct r5l_log *log, sector_t cp)
set_bit(MD_CHANGE_DEVS, &mddev->flags); set_bit(MD_CHANGE_DEVS, &mddev->flags);
} }
static ssize_t r5c_journal_mode_show(struct mddev *mddev, char *page)
{
struct r5conf *conf = mddev->private;
int ret;
if (!conf->log)
return 0;
switch (conf->log->r5c_journal_mode) {
case R5C_JOURNAL_MODE_WRITE_THROUGH:
ret = snprintf(
page, PAGE_SIZE, "[%s] %s\n",
r5c_journal_mode_str[R5C_JOURNAL_MODE_WRITE_THROUGH],
r5c_journal_mode_str[R5C_JOURNAL_MODE_WRITE_BACK]);
break;
case R5C_JOURNAL_MODE_WRITE_BACK:
ret = snprintf(
page, PAGE_SIZE, "%s [%s]\n",
r5c_journal_mode_str[R5C_JOURNAL_MODE_WRITE_THROUGH],
r5c_journal_mode_str[R5C_JOURNAL_MODE_WRITE_BACK]);
break;
default:
ret = 0;
}
return ret;
}
static ssize_t r5c_journal_mode_store(struct mddev *mddev,
const char *page, size_t length)
{
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)
return -EINVAL;
mddev_suspend(mddev);
conf->log->r5c_journal_mode = val;
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;
}
struct md_sysfs_entry
r5c_journal_mode = __ATTR(journal_mode, 0644,
r5c_journal_mode_show, r5c_journal_mode_store);
/* /*
* Try handle write operation in caching phase. This function should only * Try handle write operation in caching phase. This function should only
* be called in write-back mode. * be called in write-back mode.
......
...@@ -6319,6 +6319,7 @@ static struct attribute *raid5_attrs[] = { ...@@ -6319,6 +6319,7 @@ static struct attribute *raid5_attrs[] = {
&raid5_group_thread_cnt.attr, &raid5_group_thread_cnt.attr,
&raid5_skip_copy.attr, &raid5_skip_copy.attr,
&raid5_rmw_level.attr, &raid5_rmw_level.attr,
&r5c_journal_mode.attr,
NULL, NULL,
}; };
static struct attribute_group raid5_attrs_group = { static struct attribute_group raid5_attrs_group = {
......
...@@ -773,4 +773,5 @@ extern void r5c_make_stripe_write_out(struct stripe_head *sh); ...@@ -773,4 +773,5 @@ extern void r5c_make_stripe_write_out(struct stripe_head *sh);
extern void r5c_flush_cache(struct r5conf *conf, int num); extern void r5c_flush_cache(struct r5conf *conf, int num);
extern void r5c_check_stripe_cache_usage(struct r5conf *conf); extern void r5c_check_stripe_cache_usage(struct r5conf *conf);
extern void r5c_check_cached_full_stripe(struct r5conf *conf); extern void r5c_check_cached_full_stripe(struct r5conf *conf);
extern struct md_sysfs_entry r5c_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