aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorHeinz Mauelshagen <heinzm@redhat.com>2017-03-22 12:44:37 -0400
committerMike Snitzer <snitzer@redhat.com>2017-03-27 11:13:47 -0400
commit78e470c26f524f4706c2555613b9641d85190cbe (patch)
treedfc665acd9116cb93a2c11809758c13352950b62
parentff3af92b4461be773337111daea80bb91b2cd545 (diff)
md: add raid4/5/6 journal mode switching API
Commit 2ded370373a4 ("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: Heinz Mauelshagen <heinzm@redhat.com> Acked-by: Shaohua Li <shli@fb.com> Signed-off-by: Mike Snitzer <snitzer@redhat.com>
-rw-r--r--drivers/md/raid5-cache.c62
-rw-r--r--drivers/md/raid5.h11
2 files changed, 45 insertions, 28 deletions
diff --git a/drivers/md/raid5-cache.c b/drivers/md/raid5-cache.c
index 3f307be01b10..218b6f37da85 100644
--- a/drivers/md/raid5-cache.c
+++ b/drivers/md/raid5-cache.c
@@ -53,16 +53,6 @@
53 */ 53 */
54#define R5L_POOL_SIZE 4 54#define R5L_POOL_SIZE 4
55 55
56/*
57 * r5c journal modes of the array: write-back or write-through.
58 * write-through mode has identical behavior as existing log only
59 * implementation.
60 */
61enum r5c_journal_mode {
62 R5C_JOURNAL_MODE_WRITE_THROUGH = 0,
63 R5C_JOURNAL_MODE_WRITE_BACK = 1,
64};
65
66static char *r5c_journal_mode_str[] = {"write-through", 56static char *r5c_journal_mode_str[] = {"write-through",
67 "write-back"}; 57 "write-back"};
68/* 58/*
@@ -2327,40 +2317,56 @@ static ssize_t r5c_journal_mode_show(struct mddev *mddev, char *page)
2327 return ret; 2317 return ret;
2328} 2318}
2329 2319
2330static ssize_t r5c_journal_mode_store(struct mddev *mddev, 2320/*
2331 const char *page, size_t length) 2321 * Set journal cache mode on @mddev (external API initially needed by dm-raid).
2322 *
2323 * @mode as defined in 'enum r5c_journal_mode'.
2324 *
2325 */
2326int r5c_journal_mode_set(struct mddev *mddev, int mode)
2332{ 2327{
2333 struct r5conf *conf = mddev->private; 2328 struct r5conf *conf = mddev->private;
2334 struct r5l_log *log = conf->log; 2329 struct r5l_log *log = conf->log;
2335 int val = -1, i;
2336 int len = length;
2337 2330
2338 if (!log) 2331 if (!log)
2339 return -ENODEV; 2332 return -ENODEV;
2340 2333
2341 if (len && page[len - 1] == '\n') 2334 if (mode < R5C_JOURNAL_MODE_WRITE_THROUGH ||
2342 len -= 1; 2335 mode > R5C_JOURNAL_MODE_WRITE_BACK)
2343 for (i = 0; i < ARRAY_SIZE(r5c_journal_mode_str); i++)
2344 if (strlen(r5c_journal_mode_str[i]) == len &&
2345 strncmp(page, r5c_journal_mode_str[i], len) == 0) {
2346 val = i;
2347 break;
2348 }
2349 if (val < R5C_JOURNAL_MODE_WRITE_THROUGH ||
2350 val > R5C_JOURNAL_MODE_WRITE_BACK)
2351 return -EINVAL; 2336 return -EINVAL;
2352 2337
2353 if (raid5_calc_degraded(conf) > 0 && 2338 if (raid5_calc_degraded(conf) > 0 &&
2354 val == R5C_JOURNAL_MODE_WRITE_BACK) 2339 mode == R5C_JOURNAL_MODE_WRITE_BACK)
2355 return -EINVAL; 2340 return -EINVAL;
2356 2341
2357 mddev_suspend(mddev); 2342 mddev_suspend(mddev);
2358 conf->log->r5c_journal_mode = val; 2343 conf->log->r5c_journal_mode = mode;
2359 mddev_resume(mddev); 2344 mddev_resume(mddev);
2360 2345
2361 pr_debug("md/raid:%s: setting r5c cache mode to %d: %s\n", 2346 pr_debug("md/raid:%s: setting r5c cache mode to %d: %s\n",
2362 mdname(mddev), val, r5c_journal_mode_str[val]); 2347 mdname(mddev), mode, r5c_journal_mode_str[mode]);
2363 return length; 2348 return 0;
2349}
2350EXPORT_SYMBOL(r5c_journal_mode_set);
2351
2352static ssize_t r5c_journal_mode_store(struct mddev *mddev,
2353 const char *page, size_t length)
2354{
2355 int mode = ARRAY_SIZE(r5c_journal_mode_str);
2356 size_t len = length;
2357
2358 if (len < 2)
2359 return -EINVAL;
2360
2361 if (page[len - 1] == '\n')
2362 len--;
2363
2364 while (mode--)
2365 if (strlen(r5c_journal_mode_str[mode]) == len &&
2366 !strncmp(page, r5c_journal_mode_str[mode], len))
2367 break;
2368
2369 return r5c_journal_mode_set(mddev, mode) ?: length;
2364} 2370}
2365 2371
2366struct md_sysfs_entry 2372struct md_sysfs_entry
diff --git a/drivers/md/raid5.h b/drivers/md/raid5.h
index 4bb27b97bf6b..ec8ca15774d7 100644
--- a/drivers/md/raid5.h
+++ b/drivers/md/raid5.h
@@ -547,6 +547,16 @@ struct r5worker_group {
547 int stripes_cnt; 547 int stripes_cnt;
548}; 548};
549 549
550/*
551 * r5c journal modes of the array: write-back or write-through.
552 * write-through mode has identical behavior as existing log only
553 * implementation.
554 */
555enum r5c_journal_mode {
556 R5C_JOURNAL_MODE_WRITE_THROUGH = 0,
557 R5C_JOURNAL_MODE_WRITE_BACK = 1,
558};
559
550enum r5_cache_state { 560enum r5_cache_state {
551 R5_INACTIVE_BLOCKED, /* release of inactive stripes blocked, 561 R5_INACTIVE_BLOCKED, /* release of inactive stripes blocked,
552 * waiting for 25% to be free 562 * waiting for 25% to be free
@@ -795,4 +805,5 @@ extern void r5c_check_cached_full_stripe(struct r5conf *conf);
795extern struct md_sysfs_entry r5c_journal_mode; 805extern struct md_sysfs_entry r5c_journal_mode;
796extern void r5c_update_on_rdev_error(struct mddev *mddev); 806extern void r5c_update_on_rdev_error(struct mddev *mddev);
797extern bool r5c_big_stripe_cached(struct r5conf *conf, sector_t sect); 807extern bool r5c_big_stripe_cached(struct r5conf *conf, sector_t sect);
808extern int r5c_journal_mode_set(struct mddev *mddev, int journal_mode);
798#endif 809#endif