* Older FDs don't have a delta sequence, so check if it is there
*/
if (p - jcr->attr < msglen) {
- ar->DeltaSeq = str_to_int32(p);
+ ar->DeltaSeq = str_to_int32(p); /* delta_seq */
}
}
goto good_rtn;
}
flags = ff_pkt->flags;
- ff_pkt->flags &= ~(FO_GZIP|FO_SPARSE);
+ ff_pkt->flags &= ~(FO_GZIP|FO_SPARSE|FO_OFFSETS);
if (flags & FO_ENCRYPT) {
rsrc_stream = STREAM_ENCRYPTED_MACOS_FORK_DATA;
} else {
int zstat;
if (ff_pkt->flags & FO_GZIP) {
- if ((ff_pkt->flags & FO_SPARSE) || (ff_pkt->flags & FO_DELTA)) {
- cbuf = (Bytef *)jcr->compress_buf + SPARSE_FADDR_SIZE;
- max_compress_len = jcr->compress_buf_size - SPARSE_FADDR_SIZE;
+ if ((ff_pkt->flags & FO_SPARSE) || (ff_pkt->flags & FO_OFFSETS)) {
+ cbuf = (Bytef *)jcr->compress_buf + OFFSET_FADDR_SIZE;
+ max_compress_len = jcr->compress_buf_size - OFFSET_FADDR_SIZE;
} else {
cbuf = (Bytef *)jcr->compress_buf;
max_compress_len = jcr->compress_buf_size; /* set max length */
#endif
if (ff_pkt->flags & FO_ENCRYPT) {
- if (ff_pkt->flags & FO_SPARSE) {
- Jmsg0(jcr, M_FATAL, 0, _("Encrypting sparse data not supported.\n"));
+ if ((ff_pkt->flags & FO_SPARSE) || (ff_pkt->flags & FO_OFFSETS)) {
+ Jmsg0(jcr, M_FATAL, 0, _("Encrypting sparse or offset data not supported.\n"));
goto err;
}
/** Allocate the cipher context */
* Make space at beginning of buffer for fileAddr because this
* same buffer will be used for writing if compression is off.
*/
- if ((ff_pkt->flags & FO_SPARSE) || (ff_pkt->flags & FO_DELTA)) {
- rbuf += SPARSE_FADDR_SIZE;
- rsize -= SPARSE_FADDR_SIZE;
+ if ((ff_pkt->flags & FO_SPARSE) || (ff_pkt->flags & FO_OFFSETS)) {
+ rbuf += OFFSET_FADDR_SIZE;
+ rsize -= OFFSET_FADDR_SIZE;
#ifdef HAVE_FREEBSD_OS
/**
* To read FreeBSD partitions, the read size must be
}
if (!allZeros) {
/** Put file address as first data in buffer */
- ser_begin(wbuf, SPARSE_FADDR_SIZE);
+ ser_begin(wbuf, OFFSET_FADDR_SIZE);
ser_uint64(fileAddr); /* store fileAddr in begin of buffer */
}
fileAddr += sd->msglen; /* update file address */
if (allZeros) {
continue; /* skip block of zeros */
}
- } else if (ff_pkt->flags & FO_DELTA) {
+ } else if (ff_pkt->flags & FO_OFFSETS) {
ser_declare;
- ser_begin(wbuf, SPARSE_FADDR_SIZE);
+ ser_begin(wbuf, OFFSET_FADDR_SIZE);
ser_uint64(ff_pkt->bfd.offset); /* store offset in begin of buffer */
}
uint32_t initial_len = 0;
ser_declare;
- if ((ff_pkt->flags & FO_SPARSE) || (ff_pkt->flags & FO_DELTA)) {
- cipher_input_len += SPARSE_FADDR_SIZE;
+ if ((ff_pkt->flags & FO_SPARSE) || (ff_pkt->flags & FO_OFFSETS)) {
+ cipher_input_len += OFFSET_FADDR_SIZE;
}
/** Encrypt the length of the input block */
}
/* Send the buffer to the Storage daemon */
- if ((ff_pkt->flags & FO_SPARSE) || (ff_pkt->flags & FO_DELTA)) {
- sd->msglen += SPARSE_FADDR_SIZE; /* include fileAddr in size */
+ if ((ff_pkt->flags & FO_SPARSE) || (ff_pkt->flags & FO_OFFSETS)) {
+ sd->msglen += OFFSET_FADDR_SIZE; /* include fileAddr in size */
}
sd->msg = wbuf; /* set correct write buffer */
if (!sd->send()) {
ff_pkt->flags &= ~FO_DELTA; /* clean delta sequence number */
ff_pkt->delta_seq = 0;
}
+ if (sp.flags & FO_OFFSETS) {
+ ff_pkt->flags |= FO_OFFSETS;
+ }
+ if (sp.flags & FO_PORTABLE_DATA) {
+ ff_pkt->flags |= FO_PORTABLE_DATA;
+ }
+ ff_pkt->flags |= FO_PLUGIN; /* data from plugin */
}
memcpy(&ff_pkt->statp, &sp.statp, sizeof(ff_pkt->statp));
* First we expect a Stream Record Header
*/
if (sscanf(sd->msg, rec_header, &VolSessionId, &VolSessionTime, &file_index,
- &rctx.stream, &rctx.size) != 5) {
+ &rctx.full_stream, &rctx.size) != 5) {
Jmsg1(jcr, M_FATAL, 0, _("Record header scan error: %s\n"), sd->msg);
goto bail_out;
}
+ /* Strip off new stream high bits */
+ rctx.stream = rctx.full_stream & STREAMMASK_TYPE;
Dmsg5(150, "Got hdr: Files=%d FilInx=%d size=%d Stream=%d, %s.\n",
jcr->JobFiles, file_index, rctx.size, rctx.stream, stream_to_ascii(rctx.stream));
unser_declare;
uint64_t faddr;
char ec1[50];
- unser_begin(*data, SPARSE_FADDR_SIZE);
+ unser_begin(*data, OFFSET_FADDR_SIZE);
unser_uint64(faddr);
if (*addr != faddr) {
*addr = faddr;
return false;
}
}
- *data += SPARSE_FADDR_SIZE;
- *length -= SPARSE_FADDR_SIZE;
+ *data += OFFSET_FADDR_SIZE;
+ *length -= OFFSET_FADDR_SIZE;
return true;
}
Dmsg2(130, "Encryption writing full block, %u bytes, remaining %u bytes in buffer\n", wsize, cipher_ctx->buf_len);
}
- if ((flags & FO_SPARSE) || (flags & FO_DELTA)) {
+ if ((flags & FO_SPARSE) || (flags & FO_OFFSETS)) {
if (!sparse_data(jcr, bfd, addr, &wbuf, &wsize)) {
goto bail_out;
}
cipher_ctx->buf_len -= cipher_ctx->packet_len;
Dmsg2(130, "Encryption writing full block, %u bytes, remaining %u bytes in buffer\n", wsize, cipher_ctx->buf_len);
- if ((flags & FO_SPARSE) || (flags & FO_DELTA)) {
+ if ((flags & FO_SPARSE) || (flags & FO_OFFSETS)) {
if (!sparse_data(jcr, bfd, addr, &wbuf, &wsize)) {
return false;
}
struct r_ctx {
JCR *jcr;
- int32_t stream;
- int32_t prev_stream;
+ int32_t stream; /* stream less new bits */
+ int32_t prev_stream; /* previous stream */
+ int32_t full_stream; /* full stream including new bits */
BFILE bfd; /* File content */
uint64_t fileAddr; /* file write address */
uint32_t size; /* Size of file */
} else {
stream = STREAM_FILE_DATA;
}
- if (ff_pkt->flags & FO_DELTA) {
+ if (ff_pkt->flags & FO_OFFSETS) {
stream = STREAM_SPARSE_DATA;
}
return 0;
}
Dmsg2(dbglvl, "Got Attr: FilInx=%d type=%d\n", attr->file_index, attr->type);
+ /*
+ * Note AR_DATA_STREAM should never be set since it is encoded
+ * at the end of the attributes.
+ */
if (attr->type & AR_DATA_STREAM) {
attr->data_stream = 1;
} else {
attr->lname = p; /* set link position */
while (*p++ != 0) /* skip link */
{ }
+ attr->delta_seq = 0;
if (attr->type == FT_RESTORE_FIRST) {
/* We have an object, so do a binary copy */
object_len = reclen + rec - p;
pm_strcpy(attr->attrEx, p); /* copy extended attributes, if any */
if (attr->data_stream) {
int64_t val;
- while (*p++ != 0) /* skip extended attributes */
+ while (*p++ != 0) /* skip extended attributes */
{ }
from_base64(&val, p);
attr->data_stream = (int32_t)val;
- }
+ } else {
+ while (*p++ != 0) /* skip extended attributes */
+ { }
+ if (p - rec < reclen) {
+ attr->delta_seq = str_to_int32(p); /* delta_seq */
+ }
+ }
}
- Dmsg7(dbglvl, "unpack_attr FI=%d Type=%d fname=%s attr=%s lname=%s attrEx=%s ds=%d\n",
+ Dmsg8(dbglvl, "unpack_attr FI=%d Type=%d fname=%s attr=%s lname=%s attrEx=%s datastr=%d delta_seq=%d\n",
attr->file_index, attr->type, attr->fname, attr->attr, attr->lname,
- attr->attrEx, attr->data_stream);
+ attr->attrEx, attr->data_stream, attr->delta_seq);
*attr->ofname = 0;
*attr->olname = 0;
return 1;
/*
Bacula® - The Network Backup Solution
- Copyright (C) 2003-2008 Free Software Foundation Europe e.V.
+ Copyright (C) 2003-2010 Free Software Foundation Europe e.V.
The main author of Bacula is Kern Sibbald, with contributions from
many others, a complete list can be found in the file AUTHORS.
*
* Kern Sibbald, June MMIII
*
- * Version $Id$
*/
#ifndef __ATTR_H_
int32_t type; /* file type FT */
int32_t file_index; /* file index */
int32_t LinkFI; /* file index to data if hard link */
+ int32_t delta_seq; /* delta sequence numbr */
uid_t uid; /* userid */
struct stat statp; /* decoded stat packet */
POOLMEM *attrEx; /* extended attributes if any */
#define get_self(x) ((delta_test*)((x)->pContext))
#define FO_DELTA (1<<28) /* Do delta on file */
+#define FO_OFFSETS (1<<30) /* Keep block offsets */
class delta_test
{
bRC state = bfuncs->checkChanges(ctx, sp);
/* Should always be bRC_OK */
sp->type = (state == bRC_Seen)? FT_NOCHG : FT_REG;
- sp->flags |= FO_DELTA;
+ sp->flags |= (FO_DELTA|FO_OFFSETS);
self->delta = sp->delta_seq + 1;
}
pm_strcpy(self->fname, files[self->delta % nb_files]);
if (rec->Stream == STREAM_SPARSE_DATA) {
ser_declare;
uint64_t faddr;
- wbuf = rec->data + SPARSE_FADDR_SIZE;
- wsize = rec->data_len - SPARSE_FADDR_SIZE;
- ser_begin(rec->data, SPARSE_FADDR_SIZE);
+ wbuf = rec->data + OFFSET_FADDR_SIZE;
+ wsize = rec->data_len - OFFSET_FADDR_SIZE;
+ ser_begin(rec->data, OFFSET_FADDR_SIZE);
unser_uint64(faddr);
if (fileAddr != faddr) {
fileAddr = faddr;
ser_declare;
uint64_t faddr;
char ec1[50];
- wbuf = rec->data + SPARSE_FADDR_SIZE;
- wsize = rec->data_len - SPARSE_FADDR_SIZE;
- ser_begin(rec->data, SPARSE_FADDR_SIZE);
+ wbuf = rec->data + OFFSET_FADDR_SIZE;
+ wsize = rec->data_len - OFFSET_FADDR_SIZE;
+ ser_begin(rec->data, OFFSET_FADDR_SIZE);
unser_uint64(faddr);
if (fileAddr != faddr) {
fileAddr = faddr;