X-Git-Url: http://dolda2000.com/gitweb/?p=vcfs.git;a=blobdiff_plain;f=blocktree.c;h=a973e8f8ec4af3a5e155361d313fb32c54b6a1c6;hp=8a3c36e8d07add4f12a224771e31e9a13ac0daef;hb=2a9c9b154356d2a19517f75983ad1ad54bf71a66;hpb=d5cf535197d5090554453b6357867d782f0d1484 diff --git a/blocktree.c b/blocktree.c index 8a3c36e..a973e8f 100644 --- a/blocktree.c +++ b/blocktree.c @@ -6,6 +6,7 @@ #include "blocktree.h" #define min(a, b) (((b) < (a))?(b):(a)) +#define ISDELOP(op) (((op).buf == NULL) && ((op).fillfn == NULL)) ssize_t btget(struct store *st, struct btnode *tree, block_t bl, void *buf, size_t len) { @@ -52,6 +53,10 @@ static int btputleaf(struct store *st, struct btnode *leaf, struct btop *op, blo struct addr na; int ret; + if(ISDELOP(*op)) { + leaf->d = 0; + return(0); + } buf = NULL; if(op->buf == NULL) { buf = op->buf = malloc(op->len); @@ -97,6 +102,10 @@ static int btputmany2(struct store *st, struct btnode *tree, struct btop *ops, i hasid = 0; for(i = 0; i < numops; ) { + if(ops[i].blk < bloff) { + errno = ERANGE; + return(-1); + } bl = ops[i].blk - bloff; if((d == 0) && (bl == 0)) { @@ -162,8 +171,15 @@ static int btputmany2(struct store *st, struct btnode *tree, struct btop *ops, i i += subops; if((sel == BT_INDSZ - 1) && (indir[sel].d == ((d - 1) | 0x80))) { + /* Filled up */ tree->d |= 0x80; f = 1; + } else if(indir[sel].d == 0) { + /* Erased */ + if(--c == 1) { + tree->d = indir[0].d; + tree->a = indir[0].a; + } } } if(hasid) { @@ -199,7 +215,14 @@ void btmkop(struct btop *op, block_t bl, void *buf, size_t len) static int opcmp(const struct btop **op1, const struct btop **op2) { - return((*op1)->blk - (*op2)->blk); + if(ISDELOP(**op1) && ISDELOP(**op2)) + return((*op2)->blk - (*op1)->blk); + else if(!ISDELOP(**op1) && ISDELOP(**op2)) + return(-1); + else if(ISDELOP(**op1) && !ISDELOP(**op2)) + return(1); + else + return((*op1)->blk - (*op2)->blk); } void btsortops(struct btop *ops, int numops) @@ -207,66 +230,6 @@ void btsortops(struct btop *ops, int numops) qsort(ops, numops, sizeof(*ops), (int (*)(const void *, const void *))opcmp); } -/* -Obsoleted - -int btappend(struct store *st, struct btnode *tree, void *buf, size_t len) -{ - int d, f; - struct btnode indir[BT_INDSZ]; - struct addr na; - block_t c; - ssize_t sz; - - d = tree->d & 0x7f; - f = tree->d & 0x80; - - if(f) { - if(storeput(st, buf, len, &na)) - return(-1); - indir[0] = *tree; - indir[1].d = 0x80; - indir[1].a = na; - if(storeput(st, indir, 2 * sizeof(*indir), &na)) - return(-1); - tree->d = d + 1; - tree->a = na; - return(0); - } - - if(d == 0) { - if(storeput(st, buf, len, &na)) - return(-1); - tree->d |= 0x80; - tree->a = na; - return(0); - } - - if((sz = storeget(st, indir, BT_INDBSZ, &tree->a)) < 0) - return(-1); - c = sz / sizeof(struct btnode); - if(!(indir[c - 1].d & 0x80) || ((indir[c - 1].d & 0x7f) < (d - 1))) { - if(btappend(st, &indir[c - 1], buf, len)) - return(-1); - if(storeput(st, indir, sz, &na)) - return(-1); - tree->a = na; - if((indir[c - 1].d & 0x80) && ((indir[c - 1].d & 0x7f) == (d - 1))) - tree->d |= 0x80; - return(0); - } - - if(storeput(st, buf, len, &na)) - return(-1); - indir[c].d = 0x80; - indir[c].a = na; - if(storeput(st, indir, sz + sizeof(struct btnode), &na)) - return(-1); - tree->a = na; - return(0); -} -*/ - block_t btcount(struct store *st, struct btnode *tree) { int d, f;