mirror of
https://github.com/Fishwaldo/Star64_linux.git
synced 2025-04-12 09:24:17 +00:00
dm writecache: support optional offset for start of device
Add an optional parameter "start_sector" to allow the start of the device to be offset by the specified number of 512-byte sectors. The sectors below this offset are not used by the writecache device and are left to be used for disk labels and/or userspace metadata (e.g. lvm). Signed-off-by: Mikulas Patocka <mpatocka@redhat.com> Signed-off-by: Mike Snitzer <snitzer@redhat.com>
This commit is contained in:
parent
021c91791a
commit
d284f8248c
2 changed files with 31 additions and 14 deletions
|
@ -15,6 +15,8 @@ Constructor parameters:
|
||||||
size)
|
size)
|
||||||
5. the number of optional parameters (the parameters with an argument
|
5. the number of optional parameters (the parameters with an argument
|
||||||
count as two)
|
count as two)
|
||||||
|
start_sector n (default: 0)
|
||||||
|
offset from the start of cache device in 512-byte sectors
|
||||||
high_watermark n (default: 50)
|
high_watermark n (default: 50)
|
||||||
start writeback when the number of used blocks reach this
|
start writeback when the number of used blocks reach this
|
||||||
watermark
|
watermark
|
||||||
|
|
|
@ -136,6 +136,7 @@ struct dm_writecache {
|
||||||
struct dm_target *ti;
|
struct dm_target *ti;
|
||||||
struct dm_dev *dev;
|
struct dm_dev *dev;
|
||||||
struct dm_dev *ssd_dev;
|
struct dm_dev *ssd_dev;
|
||||||
|
sector_t start_sector;
|
||||||
void *memory_map;
|
void *memory_map;
|
||||||
uint64_t memory_map_size;
|
uint64_t memory_map_size;
|
||||||
size_t metadata_sectors;
|
size_t metadata_sectors;
|
||||||
|
@ -293,6 +294,10 @@ static int persistent_memory_claim(struct dm_writecache *wc)
|
||||||
}
|
}
|
||||||
|
|
||||||
dax_read_unlock(id);
|
dax_read_unlock(id);
|
||||||
|
|
||||||
|
wc->memory_map += (size_t)wc->start_sector << SECTOR_SHIFT;
|
||||||
|
wc->memory_map_size -= (size_t)wc->start_sector << SECTOR_SHIFT;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
err3:
|
err3:
|
||||||
kvfree(pages);
|
kvfree(pages);
|
||||||
|
@ -311,7 +316,7 @@ static int persistent_memory_claim(struct dm_writecache *wc)
|
||||||
static void persistent_memory_release(struct dm_writecache *wc)
|
static void persistent_memory_release(struct dm_writecache *wc)
|
||||||
{
|
{
|
||||||
if (wc->memory_vmapped)
|
if (wc->memory_vmapped)
|
||||||
vunmap(wc->memory_map);
|
vunmap(wc->memory_map - ((size_t)wc->start_sector << SECTOR_SHIFT));
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct page *persistent_memory_page(void *addr)
|
static struct page *persistent_memory_page(void *addr)
|
||||||
|
@ -359,7 +364,7 @@ static void *memory_data(struct dm_writecache *wc, struct wc_entry *e)
|
||||||
|
|
||||||
static sector_t cache_sector(struct dm_writecache *wc, struct wc_entry *e)
|
static sector_t cache_sector(struct dm_writecache *wc, struct wc_entry *e)
|
||||||
{
|
{
|
||||||
return wc->metadata_sectors +
|
return wc->start_sector + wc->metadata_sectors +
|
||||||
((sector_t)e->index << (wc->block_size_bits - SECTOR_SHIFT));
|
((sector_t)e->index << (wc->block_size_bits - SECTOR_SHIFT));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -471,6 +476,7 @@ static void ssd_commit_flushed(struct dm_writecache *wc)
|
||||||
if (unlikely(region.sector + region.count > wc->metadata_sectors))
|
if (unlikely(region.sector + region.count > wc->metadata_sectors))
|
||||||
region.count = wc->metadata_sectors - region.sector;
|
region.count = wc->metadata_sectors - region.sector;
|
||||||
|
|
||||||
|
region.sector += wc->start_sector;
|
||||||
atomic_inc(&endio.count);
|
atomic_inc(&endio.count);
|
||||||
req.bi_op = REQ_OP_WRITE;
|
req.bi_op = REQ_OP_WRITE;
|
||||||
req.bi_op_flags = REQ_SYNC;
|
req.bi_op_flags = REQ_SYNC;
|
||||||
|
@ -1946,14 +1952,6 @@ static int writecache_ctr(struct dm_target *ti, unsigned argc, char **argv)
|
||||||
}
|
}
|
||||||
wc->memory_map_size = i_size_read(wc->ssd_dev->bdev->bd_inode);
|
wc->memory_map_size = i_size_read(wc->ssd_dev->bdev->bd_inode);
|
||||||
|
|
||||||
if (WC_MODE_PMEM(wc)) {
|
|
||||||
r = persistent_memory_claim(wc);
|
|
||||||
if (r) {
|
|
||||||
ti->error = "Unable to map persistent memory for cache";
|
|
||||||
goto bad;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Parse the cache block size
|
* Parse the cache block size
|
||||||
*/
|
*/
|
||||||
|
@ -1982,7 +1980,16 @@ static int writecache_ctr(struct dm_target *ti, unsigned argc, char **argv)
|
||||||
|
|
||||||
while (opt_params) {
|
while (opt_params) {
|
||||||
string = dm_shift_arg(&as), opt_params--;
|
string = dm_shift_arg(&as), opt_params--;
|
||||||
if (!strcasecmp(string, "high_watermark") && opt_params >= 1) {
|
if (!strcasecmp(string, "start_sector") && opt_params >= 1) {
|
||||||
|
unsigned long long start_sector;
|
||||||
|
string = dm_shift_arg(&as), opt_params--;
|
||||||
|
if (sscanf(string, "%llu%c", &start_sector, &dummy) != 1)
|
||||||
|
goto invalid_optional;
|
||||||
|
wc->start_sector = start_sector;
|
||||||
|
if (wc->start_sector != start_sector ||
|
||||||
|
wc->start_sector >= wc->memory_map_size >> SECTOR_SHIFT)
|
||||||
|
goto invalid_optional;
|
||||||
|
} else if (!strcasecmp(string, "high_watermark") && opt_params >= 1) {
|
||||||
string = dm_shift_arg(&as), opt_params--;
|
string = dm_shift_arg(&as), opt_params--;
|
||||||
if (sscanf(string, "%d%c", &high_wm_percent, &dummy) != 1)
|
if (sscanf(string, "%d%c", &high_wm_percent, &dummy) != 1)
|
||||||
goto invalid_optional;
|
goto invalid_optional;
|
||||||
|
@ -2039,12 +2046,20 @@ invalid_optional:
|
||||||
goto bad;
|
goto bad;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!WC_MODE_PMEM(wc)) {
|
if (WC_MODE_PMEM(wc)) {
|
||||||
|
r = persistent_memory_claim(wc);
|
||||||
|
if (r) {
|
||||||
|
ti->error = "Unable to map persistent memory for cache";
|
||||||
|
goto bad;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
struct dm_io_region region;
|
struct dm_io_region region;
|
||||||
struct dm_io_request req;
|
struct dm_io_request req;
|
||||||
size_t n_blocks, n_metadata_blocks;
|
size_t n_blocks, n_metadata_blocks;
|
||||||
uint64_t n_bitmap_bits;
|
uint64_t n_bitmap_bits;
|
||||||
|
|
||||||
|
wc->memory_map_size -= (uint64_t)wc->start_sector << SECTOR_SHIFT;
|
||||||
|
|
||||||
bio_list_init(&wc->flush_list);
|
bio_list_init(&wc->flush_list);
|
||||||
wc->flush_thread = kthread_create(writecache_flush_thread, wc, "dm_writecache_flush");
|
wc->flush_thread = kthread_create(writecache_flush_thread, wc, "dm_writecache_flush");
|
||||||
if (IS_ERR(wc->flush_thread)) {
|
if (IS_ERR(wc->flush_thread)) {
|
||||||
|
@ -2097,7 +2112,7 @@ invalid_optional:
|
||||||
}
|
}
|
||||||
|
|
||||||
region.bdev = wc->ssd_dev->bdev;
|
region.bdev = wc->ssd_dev->bdev;
|
||||||
region.sector = 0;
|
region.sector = wc->start_sector;
|
||||||
region.count = wc->metadata_sectors;
|
region.count = wc->metadata_sectors;
|
||||||
req.bi_op = REQ_OP_READ;
|
req.bi_op = REQ_OP_READ;
|
||||||
req.bi_op_flags = REQ_SYNC;
|
req.bi_op_flags = REQ_SYNC;
|
||||||
|
@ -2265,7 +2280,7 @@ static void writecache_status(struct dm_target *ti, status_type_t type,
|
||||||
|
|
||||||
static struct target_type writecache_target = {
|
static struct target_type writecache_target = {
|
||||||
.name = "writecache",
|
.name = "writecache",
|
||||||
.version = {1, 0, 0},
|
.version = {1, 1, 0},
|
||||||
.module = THIS_MODULE,
|
.module = THIS_MODULE,
|
||||||
.ctr = writecache_ctr,
|
.ctr = writecache_ctr,
|
||||||
.dtr = writecache_dtr,
|
.dtr = writecache_dtr,
|
||||||
|
|
Loading…
Add table
Reference in a new issue