2 Bacula(R) - The Network Backup Solution
4 Copyright (C) 2000-2017 Kern Sibbald
6 The original author of Bacula is Kern Sibbald, with contributions
7 from many others, a complete list can be found in the file AUTHORS.
9 You may use this file and others of this release according to the
10 license defined in the LICENSE file, which includes the Affero General
11 Public License, v3.0 ("AGPLv3") and some additional permissions and
12 terms pursuant to its AGPLv3 Section 7.
14 This notice must be preserved when any source code is
15 conveyed and/or propagated.
17 Bacula(R) is a registered trademark of Kern Sibbald.
21 * block.c -- tape block handling functions
23 * Kern Sibbald, March MMI
24 * added BB02 format October MMII
31 #ifdef DEBUG_BLOCK_CHECKSUM
32 static const bool debug_block_checksum = true;
34 static const bool debug_block_checksum = false;
37 static int debug_io_error = 0; /* # blocks to write before creating I/O error */
39 #ifdef NO_TAPE_WRITE_TEST
40 static const bool no_tape_write_test = true;
42 static const bool no_tape_write_test = false;
46 uint32_t get_len_and_clear_block(DEV_BLOCK *block, DEVICE *dev, uint32_t &pad);
47 uint32_t ser_block_header(DEV_BLOCK *block, bool do_checksum);
48 bool unser_block_header(DCR *dcr, DEVICE *dev, DEV_BLOCK *block);
51 * Write a block to the device, with locking and unlocking
53 * Returns: true on success
57 bool DCR::write_block_to_device(bool final)
63 Dmsg0(250, "Write to spool\n");
64 ok = write_block_to_spool_file(dcr);
68 if (!is_dev_locked()) { /* device already locked? */
69 /* note, do not change this to dcr->rLock */
70 dev->rLock(false); /* no, lock it */
73 if (!check_for_newvol_or_newfile(dcr)) {
75 goto bail_out; /* fatal error */
78 Dmsg1(500, "Write block to dev=%p\n", dcr->dev);
79 if (!write_block_to_dev()) {
80 Dmsg2(40, "*** Failed write_block_to_dev adata=%d block=%p\n",
82 if (job_canceled(jcr) || jcr->getJobType() == JT_SYSTEM) {
84 Dmsg2(40, "cancel=%d or SYSTEM=%d\n", job_canceled(jcr),
85 jcr->getJobType() == JT_SYSTEM);
87 bool was_adata = false;
92 /* Flush any existing JobMedia info */
93 if (!(ok = dir_create_jobmedia_record(dcr))) {
94 Jmsg(jcr, M_FATAL, 0, _("Error writing JobMedia record to catalog.\n"));
96 Dmsg1(40, "Calling fixup_device was_adata=%d...\n", was_adata);
97 ok = fixup_device_block_write_error(dcr);
104 if (ok && final && !dir_create_jobmedia_record(dcr)) {
105 Jmsg(jcr, M_FATAL, 0, _("Error writing final JobMedia record to catalog.\n"));
109 if (!dcr->is_dev_locked()) { /* did we lock dev above? */
110 /* note, do not change this to dcr->dunlock */
111 dev->Unlock(); /* unlock it now */
117 * Write a block to the device
119 * Returns: true on success or EOT
120 * false on hard error
122 bool DCR::write_block_to_dev()
125 uint32_t wlen; /* length to write */
129 uint32_t pad; /* padding or zeros written */
133 if (no_tape_write_test) {
137 if (job_canceled(jcr)) {
141 Jmsg1(jcr, M_FATAL, 0, _("Cannot write block. Device is disabled. dev=%s\n"), dev->print_name());
145 ASSERT2(block->adata == dev->adata, "Block and dev adata not same");
146 Dmsg4(200, "fd=%d adata=%d bufp-buf=%d binbuf=%d\n", dev->fd(), block->adata,
147 block->bufp-block->buf, block->binbuf);
148 ASSERT2(block->binbuf == ((uint32_t)(block->bufp - block->buf)), "binbuf badly set");
150 if (is_block_empty(block)) { /* Does block have data in it? */
151 Dmsg1(50, "return write_block_to_dev no adata=%d data to write\n", block->adata);
155 if (dev->at_weot()) {
156 Dmsg1(50, "==== FATAL: At EOM with ST_WEOT. adata=%d.\n", dev->adata);
157 dev->dev_errno = ENOSPC;
158 Jmsg1(jcr, M_FATAL, 0, _("Cannot write block. Device at EOM. dev=%s\n"), dev->print_name());
161 if (!dev->can_append()) {
162 dev->dev_errno = EIO;
163 Jmsg1(jcr, M_FATAL, 0, _("Attempt to write on read-only Volume. dev=%s\n"), dev->print_name());
164 Dmsg1(50, "Attempt to write on read-only Volume. dev=%s\n", dev->print_name());
168 if (!dev->is_open()) {
169 Jmsg1(jcr, M_FATAL, 0, _("Attempt to write on closed device=%s\n"), dev->print_name());
170 Dmsg1(50, "Attempt to write on closed device=%s\n", dev->print_name());
174 wlen = get_len_and_clear_block(block, dev, pad);
175 block->block_len = wlen;
176 dev->updateVolCatPadding(pad);
178 checksum = ser_block_header(block, dev->do_checksum());
180 if (!dev->do_size_checks(dcr, block)) {
181 Dmsg0(50, "Size check triggered. Cannot write block.\n");
185 dev->updateVolCatWrites(1);
187 dump_block(dev, block, "before write");
189 #ifdef DEBUG_BLOCK_ZEROING
190 uint32_t *bp = (uint32_t *)block->buf;
191 if (bp[0] == 0 && bp[1] == 0 && bp[2] == 0 && block->buf[12] == 0) {
192 Jmsg0(jcr, M_ABORT, 0, _("Write block header zeroed.\n"));
197 * If Adata block, we must seek to the correct address
200 ASSERT(dcr->dev->adata);
201 uint64_t cur = dev->lseek(dcr, 0, SEEK_CUR);
202 /* If we are going to create a hole, record it */
203 if (block->BlockAddr != cur) {
204 dev->lseek(dcr, block->BlockAddr, SEEK_SET);
205 Dmsg4(100, "Adata seek BlockAddr from %lld to %lld = %lld bytes adata_addr=%lld\n",
206 cur, block->BlockAddr, block->BlockAddr - cur, dev->adata_addr);
208 if (block->BlockAddr > cur) {
209 dev->updateVolCatHoleBytes(block->BlockAddr - cur);
210 } else if (block->BlockAddr < cur) {
211 Pmsg5(000, "Vol=%s cur=%lld BlockAddr=%lld adata=%d block=%p\n",
212 dev->getVolCatName(), cur, block->BlockAddr, block->adata, block);
213 Jmsg3(jcr, M_FATAL, 0, "Bad seek on adata Vol=%s BlockAddr=%lld DiskAddr=%lld. Multiple simultaneous Jobs?\n",
214 dev->getVolCatName(), block->BlockAddr, cur);
215 //Pmsg2(000, "HoleBytes would go negative cur=%lld blkaddr=%lld\n", cur, block->BlockAddr);
221 * Do write here, make a somewhat feeble attempt to recover from
222 * I/O errors, or from the OS telling us it is busy.
227 /* ***FIXME**** remove next line debug */
228 pos = dev->lseek(dcr, 0, SEEK_CUR);
230 if (retry > 0 && stat == -1 && errno == EBUSY) {
232 Dmsg4(100, "===== write retry=%d stat=%d errno=%d: ERR=%s\n",
233 retry, stat, errno, be.bstrerror());
234 bmicrosleep(5, 0); /* pause a bit if busy or lots of errors */
237 stat = dev->write(block->buf, (size_t)wlen);
238 Dmsg4(100, "%s write() BlockAddr=%lld wlen=%d Vol=%s wlen=%d\n",
239 block->adata?"Adata":"Ameta", block->BlockAddr, wlen,
240 dev->VolHdr.VolumeName);
241 } while (stat == -1 && (errno == EBUSY || errno == EIO) && retry++ < 3);
243 /* ***FIXME*** remove 2 lines debug */
244 Dmsg2(100, "Wrote %d bytes at %s\n", wlen, dev->print_addr(ed1, sizeof(ed1), pos));
245 dump_block(dev, block, "After write");
247 if (debug_block_checksum) {
248 uint32_t achecksum = ser_block_header(block, dev->do_checksum());
249 if (checksum != achecksum) {
250 Jmsg2(jcr, M_ERROR, 0, _("Block checksum changed during write: before=%u after=%u\n"),
251 checksum, achecksum);
252 dump_block(dev, block, "with checksum error");
256 #ifdef DEBUG_BLOCK_ZEROING
257 if (bp[0] == 0 && bp[1] == 0 && bp[2] == 0 && block->buf[12] == 0) {
258 Jmsg0(jcr, M_ABORT, 0, _("Write block header zeroed.\n"));
262 if (debug_io_error) {
264 if (debug_io_error == 1) { /* trigger error */
266 dev->dev_errno = EIO;
268 debug_io_error = 0; /* turn off trigger */
272 if (stat != (ssize_t)wlen) {
273 /* Some devices simply report EIO when the volume is full.
274 * With a little more thought we may be able to check
275 * capacity and distinguish real errors and EOT
276 * conditions. In any case, we probably want to
277 * simulate an End of Medium.
281 dev->clrerror(-1); /* saves errno in dev->dev_errno */
282 if (dev->dev_errno == 0) {
283 dev->dev_errno = ENOSPC; /* out of space */
285 if (dev->dev_errno != ENOSPC) {
290 dev->VolCatInfo.VolCatErrors++;
291 Jmsg4(jcr, etype, 0, _("Write error at %s on device %s Vol=%s. ERR=%s.\n"),
292 dev->print_addr(ed1, sizeof(ed1)), dev->print_name(),
293 dev->getVolCatName(), be.bstrerror());
294 if (dev->get_tape_alerts(this)) {
295 dev->show_tape_alerts(this, list_long, list_last, alert_callback);
299 dev->dev_errno = ENOSPC; /* out of space */
301 if (dev->dev_errno == ENOSPC) {
302 dev->update_freespace();
303 if (dev->is_freespace_ok() && dev->free_space < dev->min_free_space) {
305 Jmsg(jcr, M_FATAL, 0, _("Out of freespace caused End of Volume \"%s\" at %s on device %s. Write of %u bytes got %d.\n"),
306 dev->getVolCatName(),
307 dev->print_addr(ed1, sizeof(ed1)), dev->print_name(), wlen, stat);
309 dev->clear_nospace();
310 Jmsg(jcr, M_INFO, 0, _("End of Volume \"%s\" at %s on device %s. Write of %u bytes got %d.\n"),
311 dev->getVolCatName(),
312 dev->print_addr(ed1, sizeof(ed1)), dev->print_name(), wlen, stat);
315 if (chk_dbglvl(100)) {
317 Dmsg7(90, "==== Write error. fd=%d size=%u rtn=%d dev_blk=%d blk_blk=%d errno=%d: ERR=%s\n",
318 dev->fd(), wlen, stat, dev->block_num, block->BlockNumber,
319 dev->dev_errno, be.bstrerror(dev->dev_errno));
322 Dmsg0(40, "Calling terminate_writing_volume\n");
323 ok = terminate_writing_volume(dcr);
325 reread_last_block(dcr);
330 /* We successfully wrote the block, now do housekeeping */
331 Dmsg2(1300, "VolCatBytes=%lld newVolCatBytes=%lld\n", dev->VolCatInfo.VolCatBytes,
332 (dev->VolCatInfo.VolCatBytes+wlen));
333 if (!dev->setVolCatAdataBytes(block->BlockAddr + wlen)) {
334 dev->updateVolCatBytes(wlen);
335 Dmsg3(200, "AmetaBytes=%lld AdataBytes=%lld Bytes=%lld\n",
336 dev->VolCatInfo.VolCatAmetaBytes, dev->VolCatInfo.VolCatAdataBytes, dev->VolCatInfo.VolCatBytes);
338 dev->updateVolCatBlocks(1);
339 dev->LastBlock = block->BlockNumber;
340 block->BlockNumber++;
342 /* Update dcr values */
343 if (dev->is_tape()) {
344 dev->EndAddr = dev->get_full_addr();
345 if (dcr->EndAddr < dev->EndAddr) {
346 dcr->EndAddr = dev->EndAddr;
350 /* Save address of byte just written */
351 uint64_t addr = dev->file_addr + wlen - 1;
352 if (dev->is_indexed()) {
353 uint64_t full_addr = dev->get_full_addr(addr);
354 if (full_addr < dcr->EndAddr) {
355 Pmsg2(000, "Possible incorrect EndAddr oldEndAddr=%llu newEndAddr=%llu\n",
356 dcr->EndAddr, full_addr);
358 dcr->EndAddr = full_addr;
362 /* We really should use file_addr, but I am not sure it is correctly set */
363 Dmsg3(100, "Set BlockAddr from %lld to %lld adata_addr=%lld\n",
364 block->BlockAddr, block->BlockAddr + wlen, dev->adata_addr);
365 block->BlockAddr += wlen;
366 dev->adata_addr = block->BlockAddr;
368 block->BlockAddr = dev->get_full_addr() + wlen;
371 if (dev->is_indexed()) {
372 if (dcr->VolMediaId != dev->VolCatInfo.VolMediaId) {
373 Dmsg7(100, "JobMedia Vol=%s wrote=%d MediaId=%lld FI=%lu LI=%lu StartAddr=%lld EndAddr=%lld Wrote\n",
374 dcr->VolumeName, dcr->WroteVol, dcr->VolMediaId,
375 dcr->VolFirstIndex, dcr->VolLastIndex, dcr->StartAddr, dcr->EndAddr);
377 dcr->VolMediaId = dev->VolCatInfo.VolMediaId;
378 Dmsg3(150, "VolFirstIndex=%d blockFirstIndex=%d Vol=%s\n",
379 dcr->VolFirstIndex, block->FirstIndex, dcr->VolumeName);
380 if (dcr->VolFirstIndex == 0 && block->FirstIndex > 0) {
381 dcr->VolFirstIndex = block->FirstIndex;
383 if (block->LastIndex > (int32_t)dcr->VolLastIndex) {
384 dcr->VolLastIndex = block->LastIndex;
386 dcr->WroteVol = true;
389 dev->file_addr += wlen; /* update file address */
390 dev->file_size += wlen;
391 dev->usage += wlen; /* update usage counter */
393 dev->part_size += wlen;
395 dev->setVolCatInfo(false); /* Needs update */
397 Dmsg2(1300, "write_block: wrote block %d bytes=%d\n", dev->block_num, wlen);
404 * Read block with locking
407 bool DCR::read_block_from_device(bool check_block_numbers)
411 Dmsg0(250, "Enter read_block_from_device\n");
413 ok = read_block_from_dev(check_block_numbers);
415 Dmsg1(250, "Leave read_block_from_device. ok=%d\n", ok);
419 static void set_block_position(DCR *dcr, DEVICE *dev, DEV_BLOCK *block)
421 /* Used also by the Single Item Restore code to locate a particular block */
422 if (dev->is_tape()) {
423 block->BlockAddr = dev->get_full_addr();
425 } else if (!dev->adata) { /* TODO: See if we just use !dev->adata for tapes */
426 /* Note: we only update the DCR values for ameta blocks
427 * because all the indexing (JobMedia) is done with
428 * ameta blocks/records, which may point to adata.
430 block->BlockAddr = dev->get_full_addr();
436 * Read the next block into the block structure and unserialize
437 * the block header. For a file, the block may be partially
438 * or completely in the current buffer.
439 * Note: in order for bscan to generate correct JobMedia records
440 * we must be careful to update the EndAddr of the last byte read.
442 bool DCR::read_block_from_dev(bool check_block_numbers)
452 if (job_canceled(jcr)) {
453 Mmsg(dev->errmsg, _("Job failed or canceled.\n"));
454 Dmsg1(000, "%s", dev->errmsg);
459 Mmsg(dev->errmsg, _("Cannot write block. Device is disabled. dev=%s\n"), dev->print_name());
460 Jmsg1(jcr, M_FATAL, 0, "%s", dev->errmsg);
465 Mmsg(dev->errmsg, _("At EOT: attempt to read past end of Volume.\n"));
466 Dmsg1(000, "%s", dev->errmsg);
472 if (!dev->is_open()) {
473 Mmsg4(dev->errmsg, _("Attempt to read closed device: fd=%d at file:blk %u:%u on device %s\n"),
474 dev->fd(), dev->file, dev->block_num, dev->print_name());
475 Jmsg(dcr->jcr, M_FATAL, 0, "%s", dev->errmsg);
476 Pmsg4(000, "Fatal: dev=%p dcr=%p adata=%d bytes=%lld\n", dev, dcr, dev->adata,
477 VolCatInfo.VolCatAdataRBytes);
478 Pmsg1(000, "%s", dev->errmsg);
483 set_block_position(dcr, dev, block);
487 dev->dev_errno = EIO;
488 Mmsg1(dev->errmsg, _("Block buffer size looping problem on device %s\n"),
490 Dmsg1(000, "%s", dev->errmsg);
491 Jmsg(jcr, M_ERROR, 0, "%s", dev->errmsg);
496 /* See if we must open another part */
497 if (dev->at_eof() && !dev->open_next_part(dcr)) {
498 if (dev->at_eof()) { /* EOF just seen? */
499 dev->set_eot(); /* yes, error => EOT */
509 dev->lseek(dcr, dcr->block->BlockAddr, SEEK_SET);
512 pos = dev->lseek(dcr, (boffset_t)0, SEEK_CUR); /* get curr pos */
513 Dmsg2(200, "Pos for read=%s %lld\n",
514 dev->print_addr(ed1, sizeof(ed1), pos), pos);
523 if ((retry > 0 && stat == -1 && errno == EBUSY)) {
525 Dmsg4(100, "===== read retry=%d stat=%d errno=%d: ERR=%s\n",
526 retry, stat, errno, be.bstrerror());
527 bmicrosleep(10, 0); /* pause a bit if busy or lots of errors */
530 stat = dev->read(block->buf + data_len, (size_t)(block->buf_len - data_len));
534 } while (stat == -1 && (errno == EBUSY || errno == EINTR || errno == EIO) && retry++ < 3);
536 } while (data_len < block->buf_len && stat > 0 && dev->dev_type == B_FIFO_DEV);
538 Dmsg4(110, "Read() adata=%d vol=%s nbytes=%d pos=%lld\n",
539 block->adata, dev->VolHdr.VolumeName, stat < 0 ? stat : data_len, pos);
543 Dmsg2(90, "Read device fd=%d got: ERR=%s\n", dev->fd(), be.bstrerror());
545 if (reading_label) { /* Trying to read Volume label */
546 Mmsg(dev->errmsg, _("The %sVolume=%s on device=%s appears to be unlabeled.%s\n"),
547 dev->adata?"adata ":"", VolumeName, dev->print_name(),
548 dev->is_fs_nearly_full(1048576)?" Notice that the filesystem is nearly full.":"");
550 Mmsg4(dev->errmsg, _("Read error on fd=%d at addr=%s on device %s. ERR=%s.\n"),
551 dev->fd(), dev->print_addr(ed1, sizeof(ed1)), dev->print_name(), be.bstrerror());
553 Jmsg(jcr, M_ERROR, 0, "%s", dev->errmsg);
554 if (dev->get_tape_alerts(this)) {
555 dev->show_tape_alerts(this, list_long, list_last, alert_callback);
557 if (dev->at_eof()) { /* EOF just seen? */
558 dev->set_eot(); /* yes, error => EOT */
565 if (stat == 0) { /* Got EOF ! */
566 pos = dev->lseek(dcr, (boffset_t)0, SEEK_CUR); /* get curr pos */
567 pos = dev->get_full_addr(pos);
568 if (reading_label) { /* Trying to read Volume label */
569 Mmsg4(dev->errmsg, _("The %sVolume=%s on device=%s appears to be unlabeled.%s\n"),
570 dev->adata?"adata ":"", VolumeName, dev->print_name(),
571 dev->is_fs_nearly_full(1048576)?" Notice tha the filesystem is nearly full.":"");
573 Mmsg4(dev->errmsg, _("Read zero %sbytes Vol=%s at %s on device %s.\n"),
574 dev->adata?"adata ":"", dev->VolCatInfo.VolCatName,
575 dev->print_addr(ed1, sizeof(ed1), pos), dev->print_name());
578 Dmsg1(100, "%s", dev->errmsg);
579 if (dev->at_eof()) { /* EOF just seen? */
580 dev->set_eot(); /* yes, error => EOT */
585 if (dcr->EndAddr < dev->EndAddr) {
586 dcr->EndAddr = dev->EndAddr;
588 Dmsg3(150, "==== Read zero bytes. adata=%d vol=%s at %s\n", dev->adata,
589 dev->VolCatInfo.VolCatName, dev->print_addr(ed1, sizeof(ed1), pos));
590 return false; /* return eof */
593 /* Continue here for successful read */
595 block->read_len = stat; /* save length read */
597 block->binbuf = block->read_len;
598 block->block_len = block->read_len;
600 if (block->read_len == 80 &&
601 (dcr->VolCatInfo.LabelType != B_BACULA_LABEL ||
602 dcr->device->label_type != B_BACULA_LABEL)) {
603 /* ***FIXME*** should check label */
604 Dmsg2(100, "Ignore 80 byte ANSI label at %u:%u\n", dev->file, dev->block_num);
606 goto reread; /* skip ANSI/IBM label */
609 if (block->read_len < BLKHDR2_LENGTH) {
610 dev->dev_errno = EIO;
611 Mmsg3(dev->errmsg, _("Volume data error at %s! Very short block of %d bytes on device %s discarded.\n"),
612 dev->print_addr(ed1, sizeof(ed1)), block->read_len, dev->print_name());
613 Jmsg(jcr, M_ERROR, 0, "%s", dev->errmsg);
614 dev->set_short_block();
615 block->read_len = block->binbuf = 0;
616 Dmsg2(50, "set block=%p binbuf=%d\n", block, block->binbuf);
617 return false; /* return error */
620 if (!unser_block_header(this, dev, block)) {
622 dev->file_addr += block->read_len;
623 dev->file_size += block->read_len;
631 * If the block is bigger than the buffer, we reposition for
632 * re-reading the block, allocate a buffer of the correct size,
635 Dmsg3(150, "adata=%d block_len=%d buf_len=%d\n", block->adata, block->block_len, block->buf_len);
636 if (block->block_len > block->buf_len) {
637 dev->dev_errno = EIO;
638 Mmsg2(dev->errmsg, _("Block length %u is greater than buffer %u. Attempting recovery.\n"),
639 block->block_len, block->buf_len);
640 Jmsg(jcr, M_ERROR, 0, "%s", dev->errmsg);
641 Pmsg1(000, "%s", dev->errmsg);
642 /* Attempt to reposition to re-read the block */
643 if (dev->is_tape()) {
644 Dmsg0(250, "BSR for reread; block too big for buffer.\n");
646 Mmsg(dev->errmsg, "%s", dev->bstrerror());
647 if (dev->errmsg[0]) {
648 Jmsg(jcr, M_ERROR, 0, "%s", dev->errmsg);
654 Dmsg0(250, "Seek to beginning of block for reread.\n");
655 boffset_t pos = dev->lseek(dcr, (boffset_t)0, SEEK_CUR); /* get curr pos */
656 pos -= block->read_len;
657 dev->lseek(dcr, pos, SEEK_SET);
658 dev->file_addr = pos;
660 Mmsg1(dev->errmsg, _("Setting block buffer size to %u bytes.\n"), block->block_len);
661 Jmsg(jcr, M_INFO, 0, "%s", dev->errmsg);
662 Pmsg1(000, "%s", dev->errmsg);
663 /* Set new block length */
664 dev->max_block_size = block->block_len;
665 block->buf_len = block->block_len;
666 free_memory(block->buf);
667 block->buf = get_memory(block->buf_len);
670 goto reread; /* re-read block with correct block size */
673 if (block->block_len > block->read_len) {
674 dev->dev_errno = EIO;
675 Mmsg4(dev->errmsg, _("Volume data error at %u:%u! Short block of %d bytes on device %s discarded.\n"),
676 dev->file, dev->block_num, block->read_len, dev->print_name());
677 Jmsg(jcr, M_ERROR, 0, "%s", dev->errmsg);
678 dev->set_short_block();
679 block->read_len = block->binbuf = 0;
680 return false; /* return error */
683 dev->clear_short_block();
685 dev->updateVolCatReads(1);
686 dev->updateVolCatReadBytes(block->read_len);
688 /* Update dcr values */
689 if (dev->is_tape()) {
690 dev->EndAddr = dev->get_full_addr();
691 if (dcr->EndAddr < dev->EndAddr) {
692 dcr->EndAddr = dev->EndAddr;
696 /* We need to take care about a short block in EndBlock/File
699 uint32_t len = MIN(block->read_len, block->block_len);
700 uint64_t addr = dev->get_full_addr() + len - 1;
701 if (dev->is_indexed()) {
702 if (addr > dcr->EndAddr) {
708 if (dev->is_indexed()) {
709 dcr->VolMediaId = dev->VolCatInfo.VolMediaId;
711 dev->file_addr += block->read_len;
712 dev->file_size += block->read_len;
713 dev->usage += block->read_len; /* update usage counter */
716 * If we read a short block on disk,
717 * seek to beginning of next block. This saves us
718 * from shuffling blocks around in the buffer. Take a
719 * look at this from an efficiency stand point later, but
720 * it should only happen once at the end of each job.
722 * I've been lseek()ing negative relative to SEEK_CUR for 30
723 * years now. However, it seems that with the new off_t definition,
724 * it is not possible to seek negative amounts, so we use two
725 * lseek(). One to get the position, then the second to do an
726 * absolute positioning -- so much for efficiency. KES Sep 02.
728 Dmsg0(250, "At end of read block\n");
729 if (block->read_len > block->block_len && !dev->is_tape()) {
731 boffset_t pos = dev->lseek(dcr, (boffset_t)0, SEEK_CUR); /* get curr pos */
732 Dmsg1(250, "Current lseek pos=%s\n", edit_int64(pos, ed1));
733 pos -= (block->read_len - block->block_len);
734 dev->lseek(dcr, pos, SEEK_SET);
735 Dmsg3(250, "Did lseek pos=%s blk_size=%d rdlen=%d\n",
736 edit_int64(pos, ed1), block->block_len,
738 dev->file_addr = pos;
739 dev->file_size = pos;
741 Dmsg3(150, "Exit read_block read_len=%d block_len=%d binbuf=%d\n",
742 block->read_len, block->block_len, block->binbuf);
743 block->block_read = true;