parent
b8395c8a83
commit
141888fa98
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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 */
|
||||
|
|
Loading…
Reference in New Issue