Skip to content

Commit 2c7da14

Browse files
liu-song-6shligit
authored andcommitted
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: Song Liu <songliubraving@fb.com> Signed-off-by: Shaohua Li <shli@fb.com>
1 parent a39f7af commit 2c7da14

File tree

3 files changed

+67
-0
lines changed

3 files changed

+67
-0
lines changed

drivers/md/raid5-cache.c

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,8 @@ enum r5c_journal_mode {
6060
R5C_JOURNAL_MODE_WRITE_BACK = 1,
6161
};
6262

63+
static char *r5c_journal_mode_str[] = {"write-through",
64+
"write-back"};
6365
/*
6466
* raid5 cache state machine
6567
*
@@ -1617,6 +1619,69 @@ static void r5l_write_super(struct r5l_log *log, sector_t cp)
16171619
set_bit(MD_CHANGE_DEVS, &mddev->flags);
16181620
}
16191621

1622+
static ssize_t r5c_journal_mode_show(struct mddev *mddev, char *page)
1623+
{
1624+
struct r5conf *conf = mddev->private;
1625+
int ret;
1626+
1627+
if (!conf->log)
1628+
return 0;
1629+
1630+
switch (conf->log->r5c_journal_mode) {
1631+
case R5C_JOURNAL_MODE_WRITE_THROUGH:
1632+
ret = snprintf(
1633+
page, PAGE_SIZE, "[%s] %s\n",
1634+
r5c_journal_mode_str[R5C_JOURNAL_MODE_WRITE_THROUGH],
1635+
r5c_journal_mode_str[R5C_JOURNAL_MODE_WRITE_BACK]);
1636+
break;
1637+
case R5C_JOURNAL_MODE_WRITE_BACK:
1638+
ret = snprintf(
1639+
page, PAGE_SIZE, "%s [%s]\n",
1640+
r5c_journal_mode_str[R5C_JOURNAL_MODE_WRITE_THROUGH],
1641+
r5c_journal_mode_str[R5C_JOURNAL_MODE_WRITE_BACK]);
1642+
break;
1643+
default:
1644+
ret = 0;
1645+
}
1646+
return ret;
1647+
}
1648+
1649+
static ssize_t r5c_journal_mode_store(struct mddev *mddev,
1650+
const char *page, size_t length)
1651+
{
1652+
struct r5conf *conf = mddev->private;
1653+
struct r5l_log *log = conf->log;
1654+
int val = -1, i;
1655+
int len = length;
1656+
1657+
if (!log)
1658+
return -ENODEV;
1659+
1660+
if (len && page[len - 1] == '\n')
1661+
len -= 1;
1662+
for (i = 0; i < ARRAY_SIZE(r5c_journal_mode_str); i++)
1663+
if (strlen(r5c_journal_mode_str[i]) == len &&
1664+
strncmp(page, r5c_journal_mode_str[i], len) == 0) {
1665+
val = i;
1666+
break;
1667+
}
1668+
if (val < R5C_JOURNAL_MODE_WRITE_THROUGH ||
1669+
val > R5C_JOURNAL_MODE_WRITE_BACK)
1670+
return -EINVAL;
1671+
1672+
mddev_suspend(mddev);
1673+
conf->log->r5c_journal_mode = val;
1674+
mddev_resume(mddev);
1675+
1676+
pr_debug("md/raid:%s: setting r5c cache mode to %d: %s\n",
1677+
mdname(mddev), val, r5c_journal_mode_str[val]);
1678+
return length;
1679+
}
1680+
1681+
struct md_sysfs_entry
1682+
r5c_journal_mode = __ATTR(journal_mode, 0644,
1683+
r5c_journal_mode_show, r5c_journal_mode_store);
1684+
16201685
/*
16211686
* Try handle write operation in caching phase. This function should only
16221687
* be called in write-back mode.

drivers/md/raid5.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6319,6 +6319,7 @@ static struct attribute *raid5_attrs[] = {
63196319
&raid5_group_thread_cnt.attr,
63206320
&raid5_skip_copy.attr,
63216321
&raid5_rmw_level.attr,
6322+
&r5c_journal_mode.attr,
63226323
NULL,
63236324
};
63246325
static struct attribute_group raid5_attrs_group = {

drivers/md/raid5.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -773,4 +773,5 @@ extern void r5c_make_stripe_write_out(struct stripe_head *sh);
773773
extern void r5c_flush_cache(struct r5conf *conf, int num);
774774
extern void r5c_check_stripe_cache_usage(struct r5conf *conf);
775775
extern void r5c_check_cached_full_stripe(struct r5conf *conf);
776+
extern struct md_sysfs_entry r5c_journal_mode;
776777
#endif

0 commit comments

Comments
 (0)