From: Robert Spalek Date: Fri, 25 Jun 2004 13:06:00 +0000 (+0000) Subject: implemented all 3 overwrite-policies X-Git-Tag: holmes-import~1021 X-Git-Url: http://mj.ucw.cz/gitweb/?a=commitdiff_plain;h=1fb95d2e848865da5f9859a089f7ed122a0dcdb8;p=libucw.git implemented all 3 overwrite-policies --- diff --git a/lib/buck2obj.c b/lib/buck2obj.c index ef53de2a..f9375141 100644 --- a/lib/buck2obj.c +++ b/lib/buck2obj.c @@ -17,7 +17,8 @@ #include #include -#define MAX_HEADER_SIZE 1024 // extra space for the header not countet to MaxObjSize +#define MAX_HEADER_SIZE 1024 // extra space for the header not counted in MaxObjSize +#define RET_ERR(num) ({ errno = num; return NULL; }) struct buck2obj_buf { @@ -47,7 +48,7 @@ buck2obj_free(struct buck2obj_buf *buf) } static inline byte * -decode_attributes(byte *ptr, byte *end, struct odes *o) +decode_attributes(byte *ptr, byte *end, struct odes *o, uns can_overwrite) { while (ptr < end) { @@ -56,14 +57,29 @@ decode_attributes(byte *ptr, byte *end, struct odes *o) if (!len--) break; byte type = ptr[len]; - ptr[len] = 0; - obj_add_attr_ref(o, type, ptr); + if (can_overwrite == 2) + { + ptr[len] = 0; + obj_add_attr_ref(o, type, ptr); + } + else if (can_overwrite == 1) + { + ptr[len] = 0; + obj_add_attr(o, type, ptr); + ptr[len] = type; + } + else + { + byte *dup = mp_alloc(o->pool, len+1); + memcpy(dup, ptr, len); + dup[len] = 0; + obj_add_attr_ref(o, type, ptr); + } ptr += len + 1; } return ptr; } -#define RET_ERR(num) ({ errno = num; return NULL; }) struct odes * buck2obj_convert(struct buck2obj_buf *buf, struct obuck_header *hdr, struct fastbuf *body) { @@ -75,18 +91,27 @@ buck2obj_convert(struct buck2obj_buf *buf, struct obuck_header *hdr, struct fast else { /* Read all the bucket into 1 buffer, 0-copy if possible. */ + int can_overwrite = MAX(bconfig(body, BCONFIG_CAN_OVERWRITE, 0), 0); + uns overwritten; byte *ptr, *end; - uns len = bdirect_read_prepare(body, &ptr); // WARNING: must NOT use mmaped-I/O - if (len < hdr->length) + uns len = bdirect_read_prepare(body, &ptr); + if (len < hdr->length + || (can_overwrite < 2 && hdr->type == BUCKET_TYPE_V33)) { + /* Copy if the original buffer is too small. + * If it is write-protected, copy it also if it is uncompressed. */ if (hdr->length > buf->raw_len) RET_ERR(EFBIG); len = bread(body, buf->raw, hdr->length); ptr = buf->raw; + can_overwrite = 2; + overwritten = 0; } + else + overwritten = can_overwrite > 1; end = ptr + len; - ptr = decode_attributes(ptr, end, o); // header + ptr = decode_attributes(ptr, end, o, can_overwrite);// header if (hdr->type == BUCKET_TYPE_V33) ; else if (hdr->type == BUCKET_TYPE_V33_LIZARD) // decompression @@ -102,13 +127,17 @@ buck2obj_convert(struct buck2obj_buf *buf, struct obuck_header *hdr, struct fast } ptr = buf->lizard->ptr; end = ptr + len; + can_overwrite = 2; } else // unknown bucket type RET_ERR(EINVAL); - ptr = decode_attributes(ptr, end, o); // body + ASSERT(can_overwrite == 2); // because of the policy and decompression + ptr = decode_attributes(ptr, end, o, 2); // body if (ptr != end) RET_ERR(EINVAL); + if (overwritten) + bflush(body); } return o; }