First fully working version
This commit is contained in:
parent
1b5b24a179
commit
f8361d1e2e
|
@ -42,7 +42,7 @@ struct lbatpage {
|
|||
bool dirty;
|
||||
};
|
||||
|
||||
bool
|
||||
static bool
|
||||
lbatpage_ctr(struct lbatpage* lp, struct cbd_params* params)
|
||||
{
|
||||
lp->pblk = PBLK_NONE;
|
||||
|
@ -61,7 +61,7 @@ lbatpage_ctr(struct lbatpage* lp, struct cbd_params* params)
|
|||
return true;
|
||||
}
|
||||
|
||||
void
|
||||
static void
|
||||
lbatpage_dtr(struct lbatpage* lp)
|
||||
{
|
||||
lp->buf = NULL;
|
||||
|
@ -83,7 +83,7 @@ lbatpage_flush_endio(struct bio* bio)
|
|||
}
|
||||
}
|
||||
|
||||
int
|
||||
static int
|
||||
lbatpage_flush(struct lbatpage* lp)
|
||||
{
|
||||
int ret = 0;
|
||||
|
@ -111,6 +111,15 @@ out:
|
|||
return ret;
|
||||
}
|
||||
|
||||
void
|
||||
lbatpage_reset(struct lbatpage* lp, u64 pblk)
|
||||
{
|
||||
if (lp->pblk != pblk) {
|
||||
lp->pblk = pblk;
|
||||
lp->state = CACHE_STATE_UNCACHED;
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
lbatpage_read(struct lbatpage* lp)
|
||||
{
|
||||
|
@ -134,15 +143,6 @@ out:
|
|||
return ret;
|
||||
}
|
||||
|
||||
void
|
||||
lbatpage_reset(struct lbatpage* lp, u64 pblk)
|
||||
{
|
||||
if (lp->pblk != pblk) {
|
||||
lp->pblk = pblk;
|
||||
lp->state = CACHE_STATE_UNCACHED;
|
||||
}
|
||||
}
|
||||
|
||||
u8*
|
||||
lbatpage_get_buf(struct lbatpage* lp, bool rw)
|
||||
{
|
||||
|
@ -277,14 +277,12 @@ lbatpagecache_get(struct lbatpagecache* lpc, u64 pblk)
|
|||
}
|
||||
mutex_unlock(&lp->reflock);
|
||||
}
|
||||
printk(KERN_INFO "%s: all pages in use, realloc...\n", __func__);
|
||||
n = lpc->len;
|
||||
if (!lbatpagecache_realloc(lpc, lpc->len * 2)) {
|
||||
printk(KERN_ERR "%s: realloc failed\n", __func__);
|
||||
lp = NULL;
|
||||
goto out;
|
||||
}
|
||||
printk(KERN_INFO "%s: realloc done, using n=%u\n", __func__, n);
|
||||
lp = lpc->cache[n];
|
||||
mutex_lock(&lp->reflock);
|
||||
|
||||
|
|
|
@ -43,7 +43,7 @@ struct lbatview {
|
|||
struct lbatpage* pages[2];
|
||||
};
|
||||
|
||||
bool
|
||||
static bool
|
||||
lbatview_ctr(struct lbatview* lv,
|
||||
struct cbd_params* params,
|
||||
struct pbatcache* pbatcache,
|
||||
|
@ -64,7 +64,7 @@ lbatview_ctr(struct lbatview* lv,
|
|||
return true;
|
||||
}
|
||||
|
||||
void
|
||||
static void
|
||||
lbatview_dtr(struct lbatview* lv)
|
||||
{
|
||||
if (pbatcache_put(lv->pbatcache, lv->pbat) != 0) {
|
||||
|
@ -77,18 +77,16 @@ lbatview_dtr(struct lbatview* lv)
|
|||
lv->lpc = NULL;
|
||||
}
|
||||
|
||||
int
|
||||
static int
|
||||
lbatview_flush(struct lbatview* lv)
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
mutex_lock(&lv->lock);
|
||||
if (lv->state != CACHE_STATE_DIRTY) {
|
||||
if (lv->state == CACHE_STATE_ERROR) {
|
||||
ret = -EIO;
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
if (lv->pages[0]) {
|
||||
ret = lbatpagecache_put(lv->lpc, lv->pages[0]);
|
||||
lv->pages[0] = NULL;
|
||||
|
@ -118,6 +116,38 @@ out:
|
|||
return ret;
|
||||
}
|
||||
|
||||
static bool
|
||||
lbatview_reset(struct lbatview* lv, u64 pblk, u32 count)
|
||||
{
|
||||
u32 zone;
|
||||
|
||||
if (lv->pbat) { printk(KERN_ERR "%s: pbat leak\n", __func__); }
|
||||
if (lv->pages[0]) { printk(KERN_ERR "%s: lbatpage leak\n", __func__); }
|
||||
if (lv->pages[1]) { printk(KERN_ERR "%s: lbatpage leak\n", __func__); }
|
||||
|
||||
zone = zone_for_pblk(lv->params, pblk);
|
||||
lv->pbat = pbatcache_get(lv->pbatcache, zone);
|
||||
if (!lv->pbat) {
|
||||
return false;
|
||||
}
|
||||
if (count > 0) {
|
||||
lv->pages[0] = lbatpagecache_get(lv->lpc, pblk + 0);
|
||||
if (!lv->pages[0]) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
if (count > 1) {
|
||||
lv->pages[1] = lbatpagecache_get(lv->lpc, pblk + 1);
|
||||
if (!lv->pages[1]) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
lv->pblk = pblk;
|
||||
lv->state = CACHE_STATE_UNCACHED;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
int
|
||||
lbatview_read(struct lbatview* lv)
|
||||
{
|
||||
|
@ -146,43 +176,11 @@ out:
|
|||
return ret;
|
||||
}
|
||||
|
||||
bool
|
||||
lbatview_reset(struct lbatview* lv, u64 pblk, u32 count)
|
||||
{
|
||||
u32 zone;
|
||||
|
||||
if (lv->pbat) { printk(KERN_ERR "%s: pbat leak\n", __func__); }
|
||||
if (lv->pages[0]) { printk(KERN_ERR "%s: lbatpage leak\n", __func__); }
|
||||
if (lv->pages[1]) { printk(KERN_ERR "%s: lbatpage leak\n", __func__); }
|
||||
|
||||
zone = (pblk - CBD_HEADER_BLOCKS) / zone_len(lv->params);
|
||||
lv->pbat = pbatcache_get(lv->pbatcache, zone);
|
||||
if (!lv->pbat) {
|
||||
return false;
|
||||
}
|
||||
if (count > 0) {
|
||||
lv->pages[0] = lbatpagecache_get(lv->lpc, pblk + 0);
|
||||
if (!lv->pages[0]) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
if (count > 1) {
|
||||
lv->pages[1] = lbatpagecache_get(lv->lpc, pblk + 1);
|
||||
if (!lv->pages[1]) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
lv->pblk = pblk;
|
||||
lv->state = CACHE_STATE_UNCACHED;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static u64
|
||||
lbatview_alloc_pblk(struct lbatview* lv)
|
||||
{
|
||||
int ret = 0;
|
||||
u32 zone = (lv->pblk - CBD_HEADER_BLOCKS) / zone_len(lv->params);
|
||||
u32 zone = zone_for_pblk(lv->params, lv->pblk);
|
||||
u64 pblk;
|
||||
u32 zone_off;
|
||||
struct pbat* pbat;
|
||||
|
@ -262,7 +260,7 @@ static int
|
|||
lbatview_free_pblk(struct lbatview* lv, u64 pblk)
|
||||
{
|
||||
int ret = 0;
|
||||
u32 zone = (lv->pblk - CBD_HEADER_BLOCKS) / zone_len(lv->params);
|
||||
u32 zone = zone_for_pblk(lv->params, lv->pblk);
|
||||
u32 pblk_zone;
|
||||
struct pbat* pbat;
|
||||
|
||||
|
@ -274,12 +272,8 @@ lbatview_free_pblk(struct lbatview* lv, u64 pblk)
|
|||
if (ret) {
|
||||
return ret;
|
||||
}
|
||||
if (pblk < CBD_HEADER_BLOCKS) {
|
||||
printk(KERN_ERR "%s: pblk=%lu: index is in header\n", __func__, (unsigned long)pblk);
|
||||
return -EINVAL;
|
||||
}
|
||||
pblk_zone = (pblk - CBD_HEADER_BLOCKS) / zone_len(lv->params);
|
||||
if (pblk_zone >= lv->params->nr_zones) {
|
||||
pblk_zone = zone_for_pblk(lv->params, pblk);
|
||||
if (pblk_zone == ZONE_NONE || pblk_zone >= lv->params->nr_zones) {
|
||||
printk(KERN_ERR "%s: pblk=%lu: zone out of bounds\n", __func__, (unsigned long)pblk);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
@ -315,7 +309,7 @@ lbatview_free_pblk(struct lbatview* lv, u64 pblk)
|
|||
static u32
|
||||
lbatview_elem_off(struct lbatview* lv, u64 lblk)
|
||||
{
|
||||
u32 lv_zone = (lv->pblk - CBD_HEADER_BLOCKS) / zone_len(lv->params);
|
||||
u32 lv_zone = zone_for_pblk(lv->params, lv->pblk);
|
||||
/* The relative lblk in the zone. */
|
||||
u32 zone_rel_lblk = lblk - (lv_zone * lv->params->lblk_per_zone);
|
||||
/* The offset of the element in the (full) lbat. */
|
||||
|
@ -664,14 +658,12 @@ lbatviewcache_get(struct lbatviewcache* lvc, u64 lblk)
|
|||
}
|
||||
mutex_unlock(&lv->reflock);
|
||||
}
|
||||
printk(KERN_INFO "%s: all objects in use, realloc...\n", __func__);
|
||||
n = lvc->len;
|
||||
if (!lbatviewcache_realloc(lvc, lvc->len * 2)) {
|
||||
printk(KERN_ERR "%s: realloc failed\n", __func__);
|
||||
lv = NULL;
|
||||
goto out;
|
||||
}
|
||||
printk(KERN_INFO "%s: realloc done, using n=%u\n", __func__, n);
|
||||
lv = lvc->cache[n];
|
||||
mutex_lock(&lv->reflock);
|
||||
|
||||
|
|
|
@ -105,7 +105,7 @@ lblk_compress(struct lbd* lbd)
|
|||
void *dbuf = lbd->buf;
|
||||
u32 dlen = PBLK_SIZE * lblk_per_pblk(lbd->params);
|
||||
void *cbuf = lbd->lz4_cbuf;
|
||||
u32 clen = PBLK_SIZE * lblk_per_pblk(lbd->params);
|
||||
u32 clen = PBLK_SIZE * lblk_per_pblk(lbd->params) - 1;
|
||||
|
||||
ret = LZ4_compress_default(dbuf, cbuf, dlen, clen, lbd->lz4_wrkmem);
|
||||
if (ret <= 0) {
|
||||
|
@ -137,7 +137,7 @@ lblk_decompress(struct lbd* lbd, u32 clen)
|
|||
return 0;
|
||||
}
|
||||
|
||||
bool
|
||||
static bool
|
||||
lbd_ctr(struct lbd* lbd,
|
||||
struct cbd_params* params,
|
||||
struct lbatviewcache* lvc)
|
||||
|
@ -169,7 +169,7 @@ lbd_ctr(struct lbd* lbd,
|
|||
return true;
|
||||
}
|
||||
|
||||
void
|
||||
static void
|
||||
lbd_dtr(struct lbd* lbd)
|
||||
{
|
||||
if (lbatviewcache_put(lbd->lvc, lbd->lv) != 0) {
|
||||
|
@ -200,7 +200,7 @@ lbd_flush_endio(struct bio* bio)
|
|||
}
|
||||
}
|
||||
|
||||
int
|
||||
static int
|
||||
lbd_flush(struct lbd* lbd)
|
||||
{
|
||||
int ret = 0;
|
||||
|
@ -276,6 +276,22 @@ out:
|
|||
return ret;
|
||||
}
|
||||
|
||||
static bool
|
||||
lbd_reset(struct lbd* lbd, u64 lblk)
|
||||
{
|
||||
if (lbd->lv) { printk(KERN_ERR "%s: lbatview leak\n", __func__); }
|
||||
|
||||
lbd->lv = lbatviewcache_get(lbd->lvc, lblk);
|
||||
if (!lbd->lv) {
|
||||
printk(KERN_ERR "%s: lbatviewcache_get failed\n", __func__);
|
||||
return false;
|
||||
}
|
||||
lbd->lblk = lblk;
|
||||
lbd->state = CACHE_STATE_UNCACHED;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
int
|
||||
lbd_read(struct lbd* lbd)
|
||||
{
|
||||
|
@ -338,22 +354,6 @@ out:
|
|||
return ret;
|
||||
}
|
||||
|
||||
bool
|
||||
lbd_reset(struct lbd* lbd, u64 lblk)
|
||||
{
|
||||
if (lbd->lv) { printk(KERN_ERR "%s: lbatview leak\n", __func__); }
|
||||
|
||||
lbd->lv = lbatviewcache_get(lbd->lvc, lblk);
|
||||
if (!lbd->lv) {
|
||||
printk(KERN_ERR "%s: lbatviewcache_get failed\n", __func__);
|
||||
return false;
|
||||
}
|
||||
lbd->lblk = lblk;
|
||||
lbd->state = CACHE_STATE_UNCACHED;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void
|
||||
lbd_data_read(struct lbd* lbd, u32 off, u32 len, u8* buf)
|
||||
{
|
||||
|
|
|
@ -41,7 +41,7 @@ struct pbat {
|
|||
u8* buf;
|
||||
};
|
||||
|
||||
bool
|
||||
static bool
|
||||
pbat_ctr(struct pbat* pbat,
|
||||
struct cbd_params* params)
|
||||
{
|
||||
|
@ -62,7 +62,7 @@ pbat_ctr(struct pbat* pbat,
|
|||
return true;
|
||||
}
|
||||
|
||||
void
|
||||
static void
|
||||
pbat_dtr(struct pbat* pbat)
|
||||
{
|
||||
pbat->buf = NULL;
|
||||
|
@ -87,7 +87,7 @@ pbat_flush_endio(struct bio* bio)
|
|||
}
|
||||
}
|
||||
|
||||
int
|
||||
static int
|
||||
pbat_flush(struct pbat* pbat)
|
||||
{
|
||||
int ret = 0;
|
||||
|
@ -122,6 +122,15 @@ out:
|
|||
return ret;
|
||||
}
|
||||
|
||||
static void
|
||||
pbat_reset(struct pbat* pbat, u32 zone)
|
||||
{
|
||||
if (pbat->zone != zone) {
|
||||
pbat->zone = zone;
|
||||
pbat->state = CACHE_STATE_UNCACHED;
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
pbat_read(struct pbat* pbat)
|
||||
{
|
||||
|
@ -150,15 +159,6 @@ out:
|
|||
return ret;
|
||||
}
|
||||
|
||||
void
|
||||
pbat_reset(struct pbat* pbat, u32 zone)
|
||||
{
|
||||
if (pbat->zone != zone) {
|
||||
pbat->zone = zone;
|
||||
pbat->state = CACHE_STATE_UNCACHED;
|
||||
}
|
||||
}
|
||||
|
||||
u32
|
||||
pbat_zone(struct pbat* pbat)
|
||||
{
|
||||
|
@ -194,8 +194,7 @@ pbat_free(struct pbat* pbat, u64 pblk)
|
|||
u32 zone;
|
||||
u32 idx;
|
||||
|
||||
BUG_ON(pblk < CBD_HEADER_BLOCKS);
|
||||
zone = (pblk - CBD_HEADER_BLOCKS) / zone_len(pbat->params);
|
||||
zone = zone_for_pblk(pbat->params, pblk);
|
||||
BUG_ON(zone != pbat->zone);
|
||||
if (pblk < zone_data_off(pbat->params, zone)) {
|
||||
printk(KERN_ERR "%s: pblk in metadata\n", __func__);
|
||||
|
@ -329,14 +328,12 @@ pbatcache_get(struct pbatcache* pc, u32 zone)
|
|||
}
|
||||
mutex_unlock(&pbat->reflock);
|
||||
}
|
||||
printk(KERN_INFO "%s: all objects in use, realloc...\n", __func__);
|
||||
n = pc->len;
|
||||
if (!pbatcache_realloc(pc, pc->len * 2)) {
|
||||
printk(KERN_ERR "%s: realloc failed\n", __func__);
|
||||
pbat = NULL;
|
||||
goto out;
|
||||
}
|
||||
printk(KERN_INFO "%s: realloc done, using n=%u\n", __func__, n);
|
||||
pbat = pc->cache[n];
|
||||
mutex_lock(&pbat->reflock);
|
||||
|
||||
|
|
|
@ -466,6 +466,17 @@ void cbd_free_pages(struct page* pages, size_t len);
|
|||
bool cbd_alloc_pagev(struct page** pagev, size_t len);
|
||||
void cbd_free_pagev(struct page** pagev, size_t len);
|
||||
|
||||
/* Core low-level I/O */
|
||||
int pblk_read_wait(struct cbd_params* params,
|
||||
u64 pblk, u32 count, struct page** pagev);
|
||||
int pblk_read(struct cbd_params* params,
|
||||
u64 pblk, u32 count, struct page** pagev,
|
||||
pblk_endio_t endio, void* endio_priv);
|
||||
void pblk_write(struct cbd_params* params,
|
||||
u64 pblk, u32 count, struct page** pagev,
|
||||
pblk_endio_t endio, void* endio_priv);
|
||||
int pblk_endio(struct bio* bio);
|
||||
|
||||
/* Debug stuff */
|
||||
typedef unsigned char byte;
|
||||
#define MD5_DIGEST_SIZE 16
|
||||
|
@ -478,23 +489,10 @@ void md5_init(struct md5* ctx);
|
|||
void md5_update(struct md5* ctx, const void* data, size_t len);
|
||||
void md5_final(struct md5* ctx, byte* buf);
|
||||
|
||||
int pblk_read_wait(struct cbd_params* params,
|
||||
u64 pblk, u32 count, struct page** pagev);
|
||||
int pblk_read(struct cbd_params* params,
|
||||
u64 pblk, u32 count, struct page** pagev,
|
||||
pblk_endio_t endio, void* endio_priv);
|
||||
void pblk_write(struct cbd_params* params,
|
||||
u64 pblk, u32 count, struct page** pagev,
|
||||
pblk_endio_t endio, void* endio_priv);
|
||||
int pblk_endio(struct bio* bio);
|
||||
|
||||
|
||||
struct pbat;
|
||||
bool pbat_ctr(struct pbat* pbat,
|
||||
struct cbd_params* params);
|
||||
void pbat_dtr(struct pbat* pbat);
|
||||
int pbat_flush(struct pbat* pbat);
|
||||
int pbat_read(struct pbat* pbat);
|
||||
void pbat_reset(struct pbat* pbat, u32 zone);
|
||||
u32 pbat_zone(struct pbat* pbat);
|
||||
u64 pbat_alloc(struct pbat* pbat);
|
||||
int pbat_free(struct pbat* pbat, u64 pblk);
|
||||
|
@ -510,11 +508,7 @@ int pbatcache_put(struct pbatcache* pbatcache, struct pbat* pbat);
|
|||
|
||||
|
||||
struct lbatpage;
|
||||
bool lbatpage_ctr(struct lbatpage* lp, struct cbd_params* params);
|
||||
void lbatpage_dtr(struct lbatpage* lp);
|
||||
int lbatpage_flush(struct lbatpage* lp);
|
||||
int lbatpage_read(struct lbatpage* lp);
|
||||
void lbatpage_reset(struct lbatpage* lp, u64 pblk);
|
||||
u8* lbatpage_get_buf(struct lbatpage* lp, bool rw);
|
||||
void lbatpage_put_buf(struct lbatpage* lp);
|
||||
|
||||
|
@ -528,14 +522,7 @@ struct lbatpage*
|
|||
int lbatpagecache_put(struct lbatpagecache* lpc, struct lbatpage* lpi);
|
||||
|
||||
struct lbatview;
|
||||
bool lbatview_ctr(struct lbatview* lv,
|
||||
struct cbd_params* params,
|
||||
struct pbatcache* pbatcache,
|
||||
struct lbatpagecache* lpc);
|
||||
void lbatview_dtr(struct lbatview* lv);
|
||||
int lbatview_flush(struct lbatview* lv);
|
||||
int lbatview_read(struct lbatview* lv);
|
||||
bool lbatview_reset(struct lbatview* lv, u64 pblk, u32 count);
|
||||
int lbatview_elem_realloc(struct lbatview* lv, u64 lblk, u32 len);
|
||||
u32 lbatview_elem_len(struct lbatview* lv, u64 lblk);
|
||||
u64 lbatview_elem_pblk(struct lbatview* lv, u64 lblk, u32 idx);
|
||||
|
@ -550,13 +537,7 @@ struct lbatview*
|
|||
int lbatviewcache_put(struct lbatviewcache* lvc, struct lbatview* lbv);
|
||||
|
||||
struct lbd;
|
||||
bool lbd_ctr(struct lbd* lbd,
|
||||
struct cbd_params* params,
|
||||
struct lbatviewcache* lvc);
|
||||
void lbd_dtr(struct lbd* lbd);
|
||||
int lbd_flush(struct lbd* lbd);
|
||||
int lbd_read(struct lbd* lbd);
|
||||
bool lbd_reset(struct lbd* lbd, u64 lblk);
|
||||
void lbd_data_read(struct lbd* lbd, u32 off, u32 len, u8* buf);
|
||||
void lbd_data_write(struct lbd* lbd, u32 off, u32 len, const u8* buf);
|
||||
|
||||
|
|
|
@ -80,8 +80,11 @@ check_one_lblk(const struct cbd_params* params,
|
|||
printf(" lblk[%u]: len=%u\n", lblk, lba->len);
|
||||
}
|
||||
}
|
||||
else {
|
||||
printf(" lblk[%u]: EMPTY\n", lblk);
|
||||
}
|
||||
if (lba->len > PBLK_SIZE * lblk_per_pblk(params)) {
|
||||
printf(" Length out of bounds\n");
|
||||
printf(" :E: Length out of bounds\n");
|
||||
return;
|
||||
}
|
||||
c_len = (lba->len == CBD_UNCOMPRESSED) ? PBLK_SIZE * lblk_per_pblk(params) : lba->len;
|
||||
|
|
Loading…
Reference in New Issue