summaryrefslogtreecommitdiff
path: root/drivers/md/dm-log.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/md/dm-log.c')
-rw-r--r--drivers/md/dm-log.c118
1 files changed, 70 insertions, 48 deletions
diff --git a/drivers/md/dm-log.c b/drivers/md/dm-log.c
index 33e71ea6cc14..9d85d045f9d9 100644
--- a/drivers/md/dm-log.c
+++ b/drivers/md/dm-log.c
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: GPL-2.0-only
/*
* Copyright (C) 2003 Sistina Software
* Copyright (C) 2004-2008 Red Hat, Inc. All rights reserved.
@@ -182,10 +183,12 @@ void dm_dirty_log_destroy(struct dm_dirty_log *log)
}
EXPORT_SYMBOL(dm_dirty_log_destroy);
-/*-----------------------------------------------------------------
+/*
+ *---------------------------------------------------------------
* Persistent and core logs share a lot of their implementation.
* FIXME: need a reload method to be called from a resume
- *---------------------------------------------------------------*/
+ *---------------------------------------------------------------
+ */
/*
* Magic for persistent mirrors: "MiRr"
*/
@@ -223,7 +226,7 @@ struct log_c {
unsigned int region_count;
region_t sync_count;
- unsigned bitset_uint32_count;
+ unsigned int bitset_uint32_count;
uint32_t *clean_bits;
uint32_t *sync_bits;
uint32_t *recovering_bits; /* FIXME: this seems excessive */
@@ -255,28 +258,30 @@ struct log_c {
* The touched member needs to be updated every time we access
* one of the bitsets.
*/
-static inline int log_test_bit(uint32_t *bs, unsigned bit)
+static inline int log_test_bit(uint32_t *bs, unsigned int bit)
{
return test_bit_le(bit, bs) ? 1 : 0;
}
static inline void log_set_bit(struct log_c *l,
- uint32_t *bs, unsigned bit)
+ uint32_t *bs, unsigned int bit)
{
__set_bit_le(bit, bs);
l->touched_cleaned = 1;
}
static inline void log_clear_bit(struct log_c *l,
- uint32_t *bs, unsigned bit)
+ uint32_t *bs, unsigned int bit)
{
__clear_bit_le(bit, bs);
l->touched_dirtied = 1;
}
-/*----------------------------------------------------------------
+/*
+ *---------------------------------------------------------------
* Header IO
- *--------------------------------------------------------------*/
+ *--------------------------------------------------------------
+ */
static void header_to_disk(struct log_header_core *core, struct log_header_disk *disk)
{
disk->magic = cpu_to_le32(core->magic);
@@ -291,12 +296,11 @@ static void header_from_disk(struct log_header_core *core, struct log_header_dis
core->nr_regions = le64_to_cpu(disk->nr_regions);
}
-static int rw_header(struct log_c *lc, int op)
+static int rw_header(struct log_c *lc, enum req_op op)
{
- lc->io_req.bi_op = op;
- lc->io_req.bi_op_flags = 0;
+ lc->io_req.bi_opf = op;
- return dm_io(&lc->io_req, 1, &lc->header_location, NULL);
+ return dm_io(&lc->io_req, 1, &lc->header_location, NULL, IOPRIO_DEFAULT);
}
static int flush_header(struct log_c *lc)
@@ -307,10 +311,9 @@ static int flush_header(struct log_c *lc)
.count = 0,
};
- lc->io_req.bi_op = REQ_OP_WRITE;
- lc->io_req.bi_op_flags = REQ_PREFLUSH;
+ lc->io_req.bi_opf = REQ_OP_WRITE | REQ_PREFLUSH;
- return dm_io(&lc->io_req, 1, &null_location, NULL);
+ return dm_io(&lc->io_req, 1, &null_location, NULL, IOPRIO_DEFAULT);
}
static int read_header(struct log_c *log)
@@ -354,11 +357,13 @@ static int _check_region_size(struct dm_target *ti, uint32_t region_size)
return 1;
}
-/*----------------------------------------------------------------
+/*
+ *--------------------------------------------------------------
* core log constructor/destructor
*
* argv contains region_size followed optionally by [no]sync
- *--------------------------------------------------------------*/
+ *--------------------------------------------------------------
+ */
#define BYTE_SHIFT 3
static int create_log_context(struct dm_dirty_log *log, struct dm_target *ti,
unsigned int argc, char **argv,
@@ -384,8 +389,7 @@ static int create_log_context(struct dm_dirty_log *log, struct dm_target *ti,
else if (!strcmp(argv[1], "nosync"))
sync = NOSYNC;
else {
- DMWARN("unrecognised sync argument to "
- "dirty region log: %s", argv[1]);
+ DMWARN("unrecognised sync argument to dirty region log: %s", argv[1]);
return -EINVAL;
}
}
@@ -415,8 +419,7 @@ static int create_log_context(struct dm_dirty_log *log, struct dm_target *ti,
/*
* Work out how many "unsigned long"s we need to hold the bitset.
*/
- bitset_size = dm_round_up(region_count,
- sizeof(*lc->clean_bits) << BYTE_SHIFT);
+ bitset_size = dm_round_up(region_count, BITS_PER_LONG);
bitset_size >>= BYTE_SHIFT;
lc->bitset_uint32_count = bitset_size / sizeof(*lc->clean_bits);
@@ -444,10 +447,9 @@ static int create_log_context(struct dm_dirty_log *log, struct dm_target *ti,
*/
buf_size =
dm_round_up((LOG_OFFSET << SECTOR_SHIFT) + bitset_size,
- bdev_logical_block_size(lc->header_location.
- bdev));
+ bdev_logical_block_size(lc->header_location.bdev));
- if (buf_size > i_size_read(dev->bdev->bd_inode)) {
+ if (buf_size > bdev_nr_bytes(dev->bdev)) {
DMWARN("log device %s too small: need %llu bytes",
dev->name, (unsigned long long)buf_size);
kfree(lc);
@@ -528,17 +530,19 @@ static void destroy_log_context(struct log_c *lc)
static void core_dtr(struct dm_dirty_log *log)
{
- struct log_c *lc = (struct log_c *) log->context;
+ struct log_c *lc = log->context;
vfree(lc->clean_bits);
destroy_log_context(lc);
}
-/*----------------------------------------------------------------
+/*
+ *---------------------------------------------------------------------
* disk log constructor/destructor
*
* argv contains log_device region_size followed optionally by [no]sync
- *--------------------------------------------------------------*/
+ *---------------------------------------------------------------------
+ */
static int disk_ctr(struct dm_dirty_log *log, struct dm_target *ti,
unsigned int argc, char **argv)
{
@@ -565,7 +569,7 @@ static int disk_ctr(struct dm_dirty_log *log, struct dm_target *ti,
static void disk_dtr(struct dm_dirty_log *log)
{
- struct log_c *lc = (struct log_c *) log->context;
+ struct log_c *lc = log->context;
dm_put_device(lc->ti, lc->log_dev);
vfree(lc->disk_header);
@@ -585,8 +589,8 @@ static void fail_log_device(struct log_c *lc)
static int disk_resume(struct dm_dirty_log *log)
{
int r;
- unsigned i;
- struct log_c *lc = (struct log_c *) log->context;
+ unsigned int i;
+ struct log_c *lc = log->context;
size_t size = lc->bitset_uint32_count * sizeof(uint32_t);
/* read the disk header */
@@ -616,7 +620,7 @@ static int disk_resume(struct dm_dirty_log *log)
log_clear_bit(lc, lc->clean_bits, i);
/* clear any old bits -- device has shrunk */
- for (i = lc->region_count; i % (sizeof(*lc->clean_bits) << BYTE_SHIFT); i++)
+ for (i = lc->region_count; i % BITS_PER_LONG; i++)
log_clear_bit(lc, lc->clean_bits, i);
/* copy clean across to sync */
@@ -648,26 +652,30 @@ static int disk_resume(struct dm_dirty_log *log)
static uint32_t core_get_region_size(struct dm_dirty_log *log)
{
- struct log_c *lc = (struct log_c *) log->context;
+ struct log_c *lc = log->context;
+
return lc->region_size;
}
static int core_resume(struct dm_dirty_log *log)
{
- struct log_c *lc = (struct log_c *) log->context;
+ struct log_c *lc = log->context;
+
lc->sync_search = 0;
return 0;
}
static int core_is_clean(struct dm_dirty_log *log, region_t region)
{
- struct log_c *lc = (struct log_c *) log->context;
+ struct log_c *lc = log->context;
+
return log_test_bit(lc->clean_bits, region);
}
static int core_in_sync(struct dm_dirty_log *log, region_t region, int block)
{
- struct log_c *lc = (struct log_c *) log->context;
+ struct log_c *lc = log->context;
+
return log_test_bit(lc->sync_bits, region);
}
@@ -719,20 +727,22 @@ static int disk_flush(struct dm_dirty_log *log)
static void core_mark_region(struct dm_dirty_log *log, region_t region)
{
- struct log_c *lc = (struct log_c *) log->context;
+ struct log_c *lc = log->context;
+
log_clear_bit(lc, lc->clean_bits, region);
}
static void core_clear_region(struct dm_dirty_log *log, region_t region)
{
- struct log_c *lc = (struct log_c *) log->context;
+ struct log_c *lc = log->context;
+
if (likely(!lc->flush_failed))
log_set_bit(lc, lc->clean_bits, region);
}
static int core_get_resync_work(struct dm_dirty_log *log, region_t *region)
{
- struct log_c *lc = (struct log_c *) log->context;
+ struct log_c *lc = log->context;
if (lc->sync_search >= lc->region_count)
return 0;
@@ -755,13 +765,13 @@ static int core_get_resync_work(struct dm_dirty_log *log, region_t *region)
static void core_set_region_sync(struct dm_dirty_log *log, region_t region,
int in_sync)
{
- struct log_c *lc = (struct log_c *) log->context;
+ struct log_c *lc = log->context;
log_clear_bit(lc, lc->recovering_bits, region);
if (in_sync) {
log_set_bit(lc, lc->sync_bits, region);
- lc->sync_count++;
- } else if (log_test_bit(lc->sync_bits, region)) {
+ lc->sync_count++;
+ } else if (log_test_bit(lc->sync_bits, region)) {
lc->sync_count--;
log_clear_bit(lc, lc->sync_bits, region);
}
@@ -769,14 +779,16 @@ static void core_set_region_sync(struct dm_dirty_log *log, region_t region,
static region_t core_get_sync_count(struct dm_dirty_log *log)
{
- struct log_c *lc = (struct log_c *) log->context;
+ struct log_c *lc = log->context;
- return lc->sync_count;
+ return lc->sync_count;
}
#define DMEMIT_SYNC \
- if (lc->sync != DEFAULTSYNC) \
- DMEMIT("%ssync ", lc->sync == NOSYNC ? "no" : "")
+ do { \
+ if (lc->sync != DEFAULTSYNC) \
+ DMEMIT("%ssync ", lc->sync == NOSYNC ? "no" : ""); \
+ } while (0)
static int core_status(struct dm_dirty_log *log, status_type_t status,
char *result, unsigned int maxlen)
@@ -784,7 +796,7 @@ static int core_status(struct dm_dirty_log *log, status_type_t status,
int sz = 0;
struct log_c *lc = log->context;
- switch(status) {
+ switch (status) {
case STATUSTYPE_INFO:
DMEMIT("1 %s", log->type->name);
break;
@@ -793,6 +805,11 @@ static int core_status(struct dm_dirty_log *log, status_type_t status,
DMEMIT("%s %u %u ", log->type->name,
lc->sync == DEFAULTSYNC ? 1 : 2, lc->region_size);
DMEMIT_SYNC;
+ break;
+
+ case STATUSTYPE_IMA:
+ *result = '\0';
+ break;
}
return sz;
@@ -804,7 +821,7 @@ static int disk_status(struct dm_dirty_log *log, status_type_t status,
int sz = 0;
struct log_c *lc = log->context;
- switch(status) {
+ switch (status) {
case STATUSTYPE_INFO:
DMEMIT("3 %s %s %c", log->type->name, lc->log_dev->name,
lc->log_dev_flush_failed ? 'F' :
@@ -817,6 +834,11 @@ static int disk_status(struct dm_dirty_log *log, status_type_t status,
lc->sync == DEFAULTSYNC ? 2 : 3, lc->log_dev->name,
lc->region_size);
DMEMIT_SYNC;
+ break;
+
+ case STATUSTYPE_IMA:
+ *result = '\0';
+ break;
}
return sz;
@@ -886,5 +908,5 @@ module_init(dm_dirty_log_init);
module_exit(dm_dirty_log_exit);
MODULE_DESCRIPTION(DM_NAME " dirty region log");
-MODULE_AUTHOR("Joe Thornber, Heinz Mauelshagen <dm-devel@redhat.com>");
+MODULE_AUTHOR("Joe Thornber, Heinz Mauelshagen <dm-devel@lists.linux.dev>");
MODULE_LICENSE("GPL");