Orange Pi5 kernel

Deprecated Linux kernel 5.10.110 for OrangePi 5/5B/5+ boards

3 Commits   0 Branches   0 Tags
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   1) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   2)  * Copyright (C) 2017 Intel Corporation.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   3)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   4)  * This file is released under the GPL.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   5)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   6) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   7) #include "dm.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   8) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   9) #include <linux/module.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  10) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  11) struct unstripe_c {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  12) 	struct dm_dev *dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  13) 	sector_t physical_start;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  14) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  15) 	uint32_t stripes;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  16) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  17) 	uint32_t unstripe;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  18) 	sector_t unstripe_width;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  19) 	sector_t unstripe_offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  20) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  21) 	uint32_t chunk_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  22) 	u8 chunk_shift;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  23) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  24) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  25) #define DM_MSG_PREFIX "unstriped"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  26) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  27) static void cleanup_unstripe(struct unstripe_c *uc, struct dm_target *ti)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  28) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  29) 	if (uc->dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  30) 		dm_put_device(ti, uc->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  31) 	kfree(uc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  32) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  33) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  34) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  35)  * Contruct an unstriped mapping.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  36)  * <number of stripes> <chunk size> <stripe #> <dev_path> <offset>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  37)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  38) static int unstripe_ctr(struct dm_target *ti, unsigned int argc, char **argv)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  39) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  40) 	struct unstripe_c *uc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  41) 	sector_t tmp_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  42) 	unsigned long long start;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  43) 	char dummy;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  44) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  45) 	if (argc != 5) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  46) 		ti->error = "Invalid number of arguments";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  47) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  48) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  49) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  50) 	uc = kzalloc(sizeof(*uc), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  51) 	if (!uc) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  52) 		ti->error = "Memory allocation for unstriped context failed";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  53) 		return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  54) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  55) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  56) 	if (kstrtouint(argv[0], 10, &uc->stripes) || !uc->stripes) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  57) 		ti->error = "Invalid stripe count";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  58) 		goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  59) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  60) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  61) 	if (kstrtouint(argv[1], 10, &uc->chunk_size) || !uc->chunk_size) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  62) 		ti->error = "Invalid chunk_size";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  63) 		goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  64) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  65) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  66) 	if (kstrtouint(argv[2], 10, &uc->unstripe)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  67) 		ti->error = "Invalid stripe number";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  68) 		goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  69) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  70) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  71) 	if (uc->unstripe > uc->stripes && uc->stripes > 1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  72) 		ti->error = "Please provide stripe between [0, # of stripes]";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  73) 		goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  74) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  75) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  76) 	if (dm_get_device(ti, argv[3], dm_table_get_mode(ti->table), &uc->dev)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  77) 		ti->error = "Couldn't get striped device";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  78) 		goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  79) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  80) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  81) 	if (sscanf(argv[4], "%llu%c", &start, &dummy) != 1 || start != (sector_t)start) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  82) 		ti->error = "Invalid striped device offset";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  83) 		goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  84) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  85) 	uc->physical_start = start;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  86) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  87) 	uc->unstripe_offset = uc->unstripe * uc->chunk_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  88) 	uc->unstripe_width = (uc->stripes - 1) * uc->chunk_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  89) 	uc->chunk_shift = is_power_of_2(uc->chunk_size) ? fls(uc->chunk_size) - 1 : 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  90) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  91) 	tmp_len = ti->len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  92) 	if (sector_div(tmp_len, uc->chunk_size)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  93) 		ti->error = "Target length not divisible by chunk size";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  94) 		goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  95) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  96) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  97) 	if (dm_set_target_max_io_len(ti, uc->chunk_size)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  98) 		ti->error = "Failed to set max io len";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  99) 		goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) 	ti->private = uc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) err:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) 	cleanup_unstripe(uc, ti);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) 	return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) static void unstripe_dtr(struct dm_target *ti)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) 	struct unstripe_c *uc = ti->private;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) 	cleanup_unstripe(uc, ti);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) static sector_t map_to_core(struct dm_target *ti, struct bio *bio)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) 	struct unstripe_c *uc = ti->private;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) 	sector_t sector = bio->bi_iter.bi_sector;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) 	sector_t tmp_sector = sector;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) 	/* Shift us up to the right "row" on the stripe */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) 	if (uc->chunk_shift)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) 		tmp_sector >>= uc->chunk_shift;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) 	else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) 		sector_div(tmp_sector, uc->chunk_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) 	sector += uc->unstripe_width * tmp_sector;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) 	/* Account for what stripe we're operating on */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) 	return sector + uc->unstripe_offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) static int unstripe_map(struct dm_target *ti, struct bio *bio)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) 	struct unstripe_c *uc = ti->private;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) 	bio_set_dev(bio, uc->dev->bdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) 	bio->bi_iter.bi_sector = map_to_core(ti, bio) + uc->physical_start;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) 	return DM_MAPIO_REMAPPED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) static void unstripe_status(struct dm_target *ti, status_type_t type,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) 			    unsigned int status_flags, char *result, unsigned int maxlen)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) 	struct unstripe_c *uc = ti->private;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) 	unsigned int sz = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) 	switch (type) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) 	case STATUSTYPE_INFO:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) 	case STATUSTYPE_TABLE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) 		DMEMIT("%d %llu %d %s %llu",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) 		       uc->stripes, (unsigned long long)uc->chunk_size, uc->unstripe,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) 		       uc->dev->name, (unsigned long long)uc->physical_start);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) static int unstripe_iterate_devices(struct dm_target *ti,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) 				    iterate_devices_callout_fn fn, void *data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) 	struct unstripe_c *uc = ti->private;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) 	return fn(ti, uc->dev, uc->physical_start, ti->len, data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) static void unstripe_io_hints(struct dm_target *ti,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) 			       struct queue_limits *limits)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) 	struct unstripe_c *uc = ti->private;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) 	limits->chunk_sectors = uc->chunk_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) static struct target_type unstripe_target = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) 	.name = "unstriped",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) 	.version = {1, 1, 0},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) 	.module = THIS_MODULE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) 	.ctr = unstripe_ctr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) 	.dtr = unstripe_dtr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) 	.map = unstripe_map,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) 	.status = unstripe_status,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) 	.iterate_devices = unstripe_iterate_devices,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) 	.io_hints = unstripe_io_hints,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) static int __init dm_unstripe_init(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) 	return dm_register_target(&unstripe_target);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) static void __exit dm_unstripe_exit(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) 	dm_unregister_target(&unstripe_target);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) module_init(dm_unstripe_init);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) module_exit(dm_unstripe_exit);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) MODULE_DESCRIPTION(DM_NAME " unstriped target");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) MODULE_ALIAS("dm-unstriped");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) MODULE_AUTHOR("Scott Bauer <scott.bauer@intel.com>");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) MODULE_LICENSE("GPL");