Make pbat len variable

Also a bit of cleanup in lbd.c
This commit is contained in:
Tom Marshall 2019-11-03 14:55:06 -08:00
parent b8395c8a83
commit 141888fa98
6 changed files with 75 additions and 45 deletions

View File

@ -149,6 +149,7 @@ compress_read_header(struct compress* c)
printk(KERN_INFO "%s: parameters...\n", __func__);
printk(KERN_INFO " algorithm=%hu\n", (unsigned short)header.params.algorithm);
printk(KERN_INFO " compression=%hu\n", (unsigned short)header.params.compression);
printk(KERN_INFO " pbat_len=%hu\n", (unsigned short)header.params.pbat_len);
printk(KERN_INFO " lblk_shift=%hu\n", (unsigned short)header.params.lblk_shift);
printk(KERN_INFO " nr_pblk=%lu\n", (unsigned long)header.params.nr_pblk);
printk(KERN_INFO " nr_zones=%u\n", (unsigned int)header.params.nr_zones);

View File

@ -319,8 +319,9 @@ lbd_flush(struct lbd* lbd)
int err;
u32 n;
u64 pblk;
u32 count = lblk_per_pblk(lbd->params);
struct page* iopagev[count];
u32 nr_pages = lblk_per_pblk(lbd->params);
u32 count;
struct page* iopagev[1];
mutex_lock(&lbd->lock);
if (!PageDirty(lbd->pagev[0])) {
@ -365,8 +366,7 @@ lbd_flush(struct lbd* lbd)
goto out;
unlock:
count = lblk_per_pblk(lbd->params);
for (n = 0; n < count; ++n) {
for (n = 0; n < nr_pages; ++n) {
unlock_page(lbd->pagev[n]);
}
@ -433,12 +433,12 @@ static int
lbd_reset(struct lbd* lbd, u64 lblk)
{
int ret = 0;
u32 count = lblk_per_pblk(lbd->params);
u32 nr_pages = lblk_per_pblk(lbd->params);
u32 n;
if (lbd->lv) { printk(KERN_ERR "%s: lbatview leak\n", __func__); }
for (n = 0; n < count; ++n) {
for (n = 0; n < nr_pages; ++n) {
lock_page(lbd->pagev[n]);
}
lbd->lv = lbatviewcache_get(lbd->lvc, lblk);
@ -468,7 +468,7 @@ out:
if (ret) {
lbatviewcache_put(lbd->lvc, lbd->lv);
lbd->lv = NULL;
for (n = 0; n < count; ++n) {
for (n = 0; n < nr_pages; ++n) {
unlock_page(lbd->pagev[n]);
}
lbd->lblk = LBLK_NONE;

View File

@ -36,7 +36,7 @@ struct pbat {
struct mutex lock;
struct cbd_params* params;
struct page* pages;
struct page** pagev;
u8* buf;
};
@ -44,18 +44,25 @@ static bool
pbat_ctr(struct pbat* pbat,
struct cbd_params* params)
{
u32 nr_pages = pbat_len(params);
memset(pbat, 0, sizeof(struct pbat));
pbat->zone = ZONE_NONE;
mutex_init(&pbat->reflock);
pbat->ref = 0;
mutex_init(&pbat->lock);
pbat->params = params;
pbat->pages = cbd_alloc_pages(pbat_len(params));
if (!pbat->pages) {
printk(KERN_ERR "%s: Failed to alloc pbat_buf\n", __func__);
pbat->pagev = kzalloc(nr_pages * sizeof(struct page*), GFP_KERNEL);
if (!pbat->pagev) {
return false;
}
if (!cbd_alloc_pagev(pbat->pagev, nr_pages)) {
return false;
}
pbat->buf = vmap(pbat->pagev, nr_pages, VM_MAP, PAGE_KERNEL);
if (!pbat->buf) {
return false;
}
pbat->buf = page_address(pbat->pages);
return true;
}
@ -63,30 +70,44 @@ pbat_ctr(struct pbat* pbat,
static void
pbat_dtr(struct pbat* pbat)
{
lock_page(pbat->pages);
u32 nr_pages = pbat_len(pbat->params);
u32 n;
for (n = 0; n < nr_pages; ++n) {
lock_page(pbat->pagev[n]);
}
vunmap(pbat->buf);
pbat->buf = NULL;
cbd_free_pages(pbat->pages, pbat_len(pbat->params));
pbat->pages = NULL;
cbd_free_pagev(pbat->pagev, nr_pages);
kfree(pbat->pagev);
pbat->pagev = NULL;
}
static bool
pbat_error(struct pbat* pbat)
{
return PageError(pbat->pages);
u32 nr_pages = pbat_len(pbat->params);
u32 n;
for (n = 0; n < nr_pages; ++n) {
if (PageError(pbat->pagev[n])) {
return true;
}
}
return false;
}
static int
pbat_flush(struct pbat* pbat)
{
int ret = 0;
u32 count = pbat_len(pbat->params);
struct page* iopagev[count];
u64 pblk;
u32 nr_pages = pbat_len(pbat->params);
u32 n;
u8* p;
u64 pblk;
mutex_lock(&pbat->lock);
if (!PageDirty(pbat->pages)) {
if (!PageDirty(pbat->pagev[0])) {
goto unlock;
}
if (pbat_error(pbat)) {
@ -94,17 +115,15 @@ pbat_flush(struct pbat* pbat)
goto unlock;
}
pblk = pbat_off(pbat->params, pbat->zone);
p = pbat->buf;
for (n = 0; n < count; ++n, p += PBLK_SIZE) {
iopagev[n] = virt_to_page(p);
}
pblk_write(pbat->params->priv, pblk, count, iopagev);
pblk_write(pbat->params->priv, pblk, nr_pages, pbat->pagev);
mutex_unlock(&pbat->lock);
return ret;
unlock:
unlock_page(pbat->pages);
for (n = 0; n < nr_pages; ++n) {
unlock_page(pbat->pagev[n]);
}
mutex_unlock(&pbat->lock);
return ret;
@ -114,21 +133,15 @@ static int
pbat_read(struct pbat* pbat)
{
int ret = 0;
u32 count = pbat_len(pbat->params);
struct page* iopagev[count];
u32 nr_pages = pbat_len(pbat->params);
u64 pblk;
u32 n;
u8* p;
/* XXX: can't happen because pbatcache will not use a page with an error */
if (PageError(pbat->pages)) {
if (PageError(pbat->pagev[0])) {
return -EIO;
}
pblk = pbat_off(pbat->params, pbat->zone);
for (n = 0, p = pbat->buf; n < count; ++n, p += PBLK_SIZE) {
iopagev[n] = virt_to_page(p);
}
ret = pblk_read_wait(pbat->params->priv, pblk, count, iopagev);
ret = pblk_read_wait(pbat->params->priv, pblk, nr_pages, pbat->pagev);
return ret;
}
@ -137,15 +150,21 @@ static int
pbat_reset(struct pbat* pbat, u32 zone)
{
int ret = 0;
u32 nr_pages = pbat_len(pbat->params);
u32 n;
lock_page(pbat->pages);
for (n = 0; n < nr_pages; ++n) {
lock_page(pbat->pagev[n]);
}
if (pbat->zone != zone) {
pbat->zone = zone;
ret = pbat_read(pbat);
}
if (ret) {
unlock_page(pbat->pages);
for (n = 0; n < nr_pages; ++n) {
unlock_page(pbat->pagev[n]);
}
pbat->zone = ZONE_NONE;
}
@ -172,7 +191,7 @@ pbat_alloc(struct pbat* pbat)
goto out;
}
pblk = idx + zone_data_off(pbat->params, pbat->zone);
SetPageDirty(pbat->pages);
SetPageDirty(pbat->pagev[0]);
out:
mutex_unlock(&pbat->lock);
@ -182,7 +201,7 @@ out:
int
pbat_free(struct pbat* pbat, u64 pblk)
{
u32 zone_pblk_count = pbat_len(pbat->params) * PBLK_SIZE_BITS;
u32 pblk_count = pbat_len(pbat->params) * PBLK_SIZE_BITS;
u32 zone;
u32 idx;
@ -193,10 +212,10 @@ pbat_free(struct pbat* pbat, u64 pblk)
return -EINVAL;
}
idx = pblk - zone_data_off(pbat->params, zone);
BUG_ON(idx >= zone_pblk_count);
BUG_ON(idx >= pblk_count);
mutex_lock(&pbat->lock);
cbd_bitmap_free(pbat->buf, idx);
SetPageDirty(pbat->pages);
SetPageDirty(pbat->pagev[0]);
mutex_unlock(&pbat->lock);
return 0;

View File

@ -50,7 +50,8 @@ typedef enum {
} tristate_t;
int cbd_format(const char* dev,
uint64_t psize, uint16_t lshift, uint64_t lsize,
uint64_t psize, uint16_t pbatlen,
uint16_t lshift, uint64_t lsize,
enum cbd_alg alg, uint level);
int cbd_open(const char* dev,
const char* name);

View File

@ -39,6 +39,7 @@ enum cbd_alg {
struct cbd_params {
u8 algorithm; /* enum cbd_alg */
u8 compression; /* 0..9 */
u16 pbat_len;
u16 lblk_shift;
u64 nr_pblk;
u32 nr_zones;
@ -197,7 +198,7 @@ lblk_per_pblk(const struct cbd_params* params)
static inline u32
pbat_len(const struct cbd_params* params)
{
return 1;
return params->pbat_len;
}
static inline u32
@ -296,6 +297,7 @@ cbd_header_get(const u8* buf, struct cbd_header* header)
header->version_minor = get16_le(&buf);
header->params.algorithm = get_byte(&buf);
header->params.compression = get_byte(&buf);
header->params.pbat_len = get16_le(&buf);
header->params.lblk_shift = get16_le(&buf);
header->params.nr_pblk = get64_le(&buf);
header->params.nr_zones = get32_le(&buf);
@ -310,6 +312,7 @@ cbd_header_put(u8* buf, const struct cbd_header* header)
put16_le(&buf, header->version_minor);
put_byte(&buf, header->params.algorithm);
put_byte(&buf, header->params.compression);
put16_le(&buf, header->params.pbat_len);
put16_le(&buf, header->params.lblk_shift);
put64_le(&buf, header->params.nr_pblk);
put32_le(&buf, header->params.nr_zones);

View File

@ -27,7 +27,8 @@ pblk_write(int fd, u64 pblk, u32 count, const u8* data)
int
cbd_format(const char* dev,
uint64_t psize, uint16_t lshift, uint64_t lsize,
uint64_t psize, uint16_t pbatlen,
uint16_t lshift, uint64_t lsize,
enum cbd_alg alg, uint level)
{
int devfd;
@ -50,6 +51,9 @@ cbd_format(const char* dev,
}
psize = pos / PBLK_SIZE * PBLK_SIZE;
}
if (!pbatlen) {
pbatlen = 1;
}
if (!lshift) {
lshift = CBD_DEFAULT_LOGICAL_BLOCK_SHIFT;
}
@ -77,6 +81,7 @@ cbd_format(const char* dev,
printf("%s: paramaters...\n", __func__);
printf(" psize=%lu\n", (unsigned long)psize);
printf(" pbatlen=%hu\n", (unsigned short)pbatlen);
printf(" lshift=%hu\n", (unsigned short)lshift);
printf(" lsize=%lu\n", (unsigned long)lsize);
memset(&header, 0, sizeof(header));
@ -85,6 +90,7 @@ cbd_format(const char* dev,
header.version_minor = CBD_VERSION_MINOR;
header.params.algorithm = alg;
header.params.compression = level;
header.params.pbat_len = pbatlen;
header.params.lblk_shift = lshift;
header.params.nr_pblk = psize / PBLK_SIZE;
/* XXX: Initial estimate */