aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/md/raid5-ppl.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/md/raid5-ppl.c')
-rw-r--r--drivers/md/raid5-ppl.c63
1 files changed, 63 insertions, 0 deletions
diff --git a/drivers/md/raid5-ppl.c b/drivers/md/raid5-ppl.c
index 0b096ddc9c1e..17e9e7d51097 100644
--- a/drivers/md/raid5-ppl.c
+++ b/drivers/md/raid5-ppl.c
@@ -20,6 +20,7 @@
20#include <linux/raid/md_p.h> 20#include <linux/raid/md_p.h>
21#include "md.h" 21#include "md.h"
22#include "raid5.h" 22#include "raid5.h"
23#include "raid5-log.h"
23 24
24/* 25/*
25 * PPL consists of a 4KB header (struct ppl_header) and at least 128KB for 26 * PPL consists of a 4KB header (struct ppl_header) and at least 128KB for
@@ -115,6 +116,8 @@ struct ppl_conf {
115 /* stripes to retry if failed to allocate io_unit */ 116 /* stripes to retry if failed to allocate io_unit */
116 struct list_head no_mem_stripes; 117 struct list_head no_mem_stripes;
117 spinlock_t no_mem_stripes_lock; 118 spinlock_t no_mem_stripes_lock;
119
120 unsigned short write_hint;
118}; 121};
119 122
120struct ppl_log { 123struct ppl_log {
@@ -474,6 +477,7 @@ static void ppl_submit_iounit(struct ppl_io_unit *io)
474 bio_set_dev(bio, log->rdev->bdev); 477 bio_set_dev(bio, log->rdev->bdev);
475 bio->bi_iter.bi_sector = log->next_io_sector; 478 bio->bi_iter.bi_sector = log->next_io_sector;
476 bio_add_page(bio, io->header_page, PAGE_SIZE, 0); 479 bio_add_page(bio, io->header_page, PAGE_SIZE, 0);
480 bio->bi_write_hint = ppl_conf->write_hint;
477 481
478 pr_debug("%s: log->current_io_sector: %llu\n", __func__, 482 pr_debug("%s: log->current_io_sector: %llu\n", __func__,
479 (unsigned long long)log->next_io_sector); 483 (unsigned long long)log->next_io_sector);
@@ -503,6 +507,7 @@ static void ppl_submit_iounit(struct ppl_io_unit *io)
503 bio = bio_alloc_bioset(GFP_NOIO, BIO_MAX_PAGES, 507 bio = bio_alloc_bioset(GFP_NOIO, BIO_MAX_PAGES,
504 &ppl_conf->bs); 508 &ppl_conf->bs);
505 bio->bi_opf = prev->bi_opf; 509 bio->bi_opf = prev->bi_opf;
510 bio->bi_write_hint = prev->bi_write_hint;
506 bio_copy_dev(bio, prev); 511 bio_copy_dev(bio, prev);
507 bio->bi_iter.bi_sector = bio_end_sector(prev); 512 bio->bi_iter.bi_sector = bio_end_sector(prev);
508 bio_add_page(bio, sh->ppl_page, PAGE_SIZE, 0); 513 bio_add_page(bio, sh->ppl_page, PAGE_SIZE, 0);
@@ -1407,6 +1412,7 @@ int ppl_init_log(struct r5conf *conf)
1407 atomic64_set(&ppl_conf->seq, 0); 1412 atomic64_set(&ppl_conf->seq, 0);
1408 INIT_LIST_HEAD(&ppl_conf->no_mem_stripes); 1413 INIT_LIST_HEAD(&ppl_conf->no_mem_stripes);
1409 spin_lock_init(&ppl_conf->no_mem_stripes_lock); 1414 spin_lock_init(&ppl_conf->no_mem_stripes_lock);
1415 ppl_conf->write_hint = RWF_WRITE_LIFE_NOT_SET;
1410 1416
1411 if (!mddev->external) { 1417 if (!mddev->external) {
1412 ppl_conf->signature = ~crc32c_le(~0, mddev->uuid, sizeof(mddev->uuid)); 1418 ppl_conf->signature = ~crc32c_le(~0, mddev->uuid, sizeof(mddev->uuid));
@@ -1501,3 +1507,60 @@ int ppl_modify_log(struct r5conf *conf, struct md_rdev *rdev, bool add)
1501 1507
1502 return ret; 1508 return ret;
1503} 1509}
1510
1511static ssize_t
1512ppl_write_hint_show(struct mddev *mddev, char *buf)
1513{
1514 size_t ret = 0;
1515 struct r5conf *conf;
1516 struct ppl_conf *ppl_conf = NULL;
1517
1518 spin_lock(&mddev->lock);
1519 conf = mddev->private;
1520 if (conf && raid5_has_ppl(conf))
1521 ppl_conf = conf->log_private;
1522 ret = sprintf(buf, "%d\n", ppl_conf ? ppl_conf->write_hint : 0);
1523 spin_unlock(&mddev->lock);
1524
1525 return ret;
1526}
1527
1528static ssize_t
1529ppl_write_hint_store(struct mddev *mddev, const char *page, size_t len)
1530{
1531 struct r5conf *conf;
1532 struct ppl_conf *ppl_conf;
1533 int err = 0;
1534 unsigned short new;
1535
1536 if (len >= PAGE_SIZE)
1537 return -EINVAL;
1538 if (kstrtou16(page, 10, &new))
1539 return -EINVAL;
1540
1541 err = mddev_lock(mddev);
1542 if (err)
1543 return err;
1544
1545 conf = mddev->private;
1546 if (!conf) {
1547 err = -ENODEV;
1548 } else if (raid5_has_ppl(conf)) {
1549 ppl_conf = conf->log_private;
1550 if (!ppl_conf)
1551 err = -EINVAL;
1552 else
1553 ppl_conf->write_hint = new;
1554 } else {
1555 err = -EINVAL;
1556 }
1557
1558 mddev_unlock(mddev);
1559
1560 return err ?: len;
1561}
1562
1563struct md_sysfs_entry
1564ppl_write_hint = __ATTR(ppl_write_hint, S_IRUGO | S_IWUSR,
1565 ppl_write_hint_show,
1566 ppl_write_hint_store);