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_WARNING, 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)
451 if (job_canceled(jcr)) {
452 Mmsg(dev->errmsg, _("Job failed or canceled.\n"));
453 Dmsg1(000, "%s", dev->errmsg);
458 Mmsg(dev->errmsg, _("Cannot write block. Device is disabled. dev=%s\n"), dev->print_name());
459 Jmsg1(jcr, M_FATAL, 0, "%s", dev->errmsg);
464 Mmsg(dev->errmsg, _("At EOT: attempt to read past end of Volume.\n"));
465 Dmsg1(000, "%s", dev->errmsg);
471 if (!dev->is_open()) {
472 Mmsg4(dev->errmsg, _("Attempt to read closed device: fd=%d at file:blk %u:%u on device %s\n"),
473 dev->fd(), dev->file, dev->block_num, dev->print_name());
474 Jmsg(dcr->jcr, M_FATAL, 0, "%s", dev->errmsg);
475 Pmsg4(000, "Fatal: dev=%p dcr=%p adata=%d bytes=%lld\n", dev, dcr, dev->adata,
476 VolCatInfo.VolCatAdataRBytes);
477 Pmsg1(000, "%s", dev->errmsg);
482 set_block_position(dcr, dev, block);
486 dev->dev_errno = EIO;
487 Mmsg1(dev->errmsg, _("Block buffer size looping problem on device %s\n"),
489 Dmsg1(000, "%s", dev->errmsg);
490 Jmsg(jcr, M_ERROR, 0, "%s", dev->errmsg);
495 /* See if we must open another part */
496 if (dev->at_eof() && !dev->open_next_part(dcr)) {
497 if (dev->at_eof()) { /* EOF just seen? */
498 dev->set_eot(); /* yes, error => EOT */
508 dev->lseek(dcr, dcr->block->BlockAddr, SEEK_SET);
511 pos = dev->lseek(dcr, (boffset_t)0, SEEK_CUR); /* get curr pos */
512 Dmsg2(200, "Pos for read=%s %lld\n",
513 dev->print_addr(ed1, sizeof(ed1), pos), pos);
516 if ((retry > 0 && stat == -1 && errno == EBUSY)) {
518 Dmsg4(100, "===== read retry=%d stat=%d errno=%d: ERR=%s\n",
519 retry, stat, errno, be.bstrerror());
520 bmicrosleep(10, 0); /* pause a bit if busy or lots of errors */
523 stat = dev->read(block->buf, (size_t)block->buf_len);
525 } while (stat == -1 && (errno == EBUSY || errno == EINTR || errno == EIO) && retry++ < 3);
526 Dmsg4(110, "Read() adata=%d vol=%s nbytes=%d pos=%lld\n",
527 block->adata, dev->VolHdr.VolumeName, stat, pos);
531 Dmsg2(90, "Read device fd=%d got: ERR=%s\n", dev->fd(), be.bstrerror());
533 if (reading_label) { /* Trying to read Volume label */
534 Mmsg(dev->errmsg, _("The %sVolume=%s on device=%s appears to be unlabeled.%s\n"),
535 dev->adata?"adata ":"", VolumeName, dev->print_name(),
536 dev->is_fs_nearly_full(1048576)?" Notice that the filesystem is nearly full.":"");
538 Mmsg4(dev->errmsg, _("Read error on fd=%d at addr=%s on device %s. ERR=%s.\n"),
539 dev->fd(), dev->print_addr(ed1, sizeof(ed1)), dev->print_name(), be.bstrerror());
541 Jmsg(jcr, M_ERROR, 0, "%s", dev->errmsg);
542 if (dev->get_tape_alerts(this)) {
543 dev->show_tape_alerts(this, list_long, list_last, alert_callback);
545 if (dev->at_eof()) { /* EOF just seen? */
546 dev->set_eot(); /* yes, error => EOT */
550 if (stat == 0) { /* Got EOF ! */
551 pos = dev->lseek(dcr, (boffset_t)0, SEEK_CUR); /* get curr pos */
552 pos = dev->get_full_addr(pos);
553 if (reading_label) { /* Trying to read Volume label */
554 Mmsg4(dev->errmsg, _("The %sVolume=%s on device=%s appears to be unlabeled.%s\n"),
555 dev->adata?"adata ":"", VolumeName, dev->print_name(),
556 dev->is_fs_nearly_full(1048576)?" Notice tha the filesystem is nearly full.":"");
558 Mmsg4(dev->errmsg, _("Read zero %sbytes Vol=%s at %s on device %s.\n"),
559 dev->adata?"adata ":"", dev->VolCatInfo.VolCatName,
560 dev->print_addr(ed1, sizeof(ed1), pos), dev->print_name());
563 Dmsg1(100, "%s", dev->errmsg);
564 if (dev->at_eof()) { /* EOF just seen? */
565 dev->set_eot(); /* yes, error => EOT */
570 if (dcr->EndAddr < dev->EndAddr) {
571 dcr->EndAddr = dev->EndAddr;
573 Dmsg3(150, "==== Read zero bytes. adata=%d vol=%s at %s\n", dev->adata,
574 dev->VolCatInfo.VolCatName, dev->print_addr(ed1, sizeof(ed1), pos));
575 return false; /* return eof */
578 /* Continue here for successful read */
580 block->read_len = stat; /* save length read */
582 block->binbuf = block->read_len;
583 block->block_len = block->read_len;
585 if (block->read_len == 80 &&
586 (dcr->VolCatInfo.LabelType != B_BACULA_LABEL ||
587 dcr->device->label_type != B_BACULA_LABEL)) {
588 /* ***FIXME*** should check label */
589 Dmsg2(100, "Ignore 80 byte ANSI label at %u:%u\n", dev->file, dev->block_num);
591 goto reread; /* skip ANSI/IBM label */
594 if (block->read_len < BLKHDR2_LENGTH) {
595 dev->dev_errno = EIO;
596 Mmsg3(dev->errmsg, _("Volume data error at %s! Very short block of %d bytes on device %s discarded.\n"),
597 dev->print_addr(ed1, sizeof(ed1)), block->read_len, dev->print_name());
598 Jmsg(jcr, M_ERROR, 0, "%s", dev->errmsg);
599 dev->set_short_block();
600 block->read_len = block->binbuf = 0;
601 Dmsg2(50, "set block=%p binbuf=%d\n", block, block->binbuf);
602 return false; /* return error */
605 if (!unser_block_header(this, dev, block)) {
607 dev->file_addr += block->read_len;
608 dev->file_size += block->read_len;
616 * If the block is bigger than the buffer, we reposition for
617 * re-reading the block, allocate a buffer of the correct size,
620 Dmsg3(150, "adata=%d block_len=%d buf_len=%d\n", block->adata, block->block_len, block->buf_len);
621 if (block->block_len > block->buf_len) {
622 dev->dev_errno = EIO;
623 Mmsg2(dev->errmsg, _("Block length %u is greater than buffer %u. Attempting recovery.\n"),
624 block->block_len, block->buf_len);
625 Jmsg(jcr, M_ERROR, 0, "%s", dev->errmsg);
626 Pmsg1(000, "%s", dev->errmsg);
627 /* Attempt to reposition to re-read the block */
628 if (dev->is_tape()) {
629 Dmsg0(250, "BSR for reread; block too big for buffer.\n");
631 Mmsg(dev->errmsg, "%s", dev->bstrerror());
632 if (dev->errmsg[0]) {
633 Jmsg(jcr, M_ERROR, 0, "%s", dev->errmsg);
639 Dmsg0(250, "Seek to beginning of block for reread.\n");
640 boffset_t pos = dev->lseek(dcr, (boffset_t)0, SEEK_CUR); /* get curr pos */
641 pos -= block->read_len;
642 dev->lseek(dcr, pos, SEEK_SET);
643 dev->file_addr = pos;
645 Mmsg1(dev->errmsg, _("Setting block buffer size to %u bytes.\n"), block->block_len);
646 Jmsg(jcr, M_INFO, 0, "%s", dev->errmsg);
647 Pmsg1(000, "%s", dev->errmsg);
648 /* Set new block length */
649 dev->max_block_size = block->block_len;
650 block->buf_len = block->block_len;
651 free_memory(block->buf);
652 block->buf = get_memory(block->buf_len);
655 goto reread; /* re-read block with correct block size */
658 if (block->block_len > block->read_len) {
659 dev->dev_errno = EIO;
660 Mmsg4(dev->errmsg, _("Volume data error at %u:%u! Short block of %d bytes on device %s discarded.\n"),
661 dev->file, dev->block_num, block->read_len, dev->print_name());
662 Jmsg(jcr, M_ERROR, 0, "%s", dev->errmsg);
663 dev->set_short_block();
664 block->read_len = block->binbuf = 0;
665 return false; /* return error */
668 dev->clear_short_block();
670 dev->updateVolCatReads(1);
671 dev->updateVolCatReadBytes(block->read_len);
673 /* Update dcr values */
674 if (dev->is_tape()) {
675 dev->EndAddr = dev->get_full_addr();
676 if (dcr->EndAddr < dev->EndAddr) {
677 dcr->EndAddr = dev->EndAddr;
681 /* We need to take care about a short block in EndBlock/File
684 uint32_t len = MIN(block->read_len, block->block_len);
685 uint64_t addr = dev->get_full_addr() + len - 1;
686 if (dev->is_indexed()) {
687 if (addr > dcr->EndAddr) {
693 if (dev->is_indexed()) {
694 dcr->VolMediaId = dev->VolCatInfo.VolMediaId;
696 dev->file_addr += block->read_len;
697 dev->file_size += block->read_len;
698 dev->usage += block->read_len; /* update usage counter */
701 * If we read a short block on disk,
702 * seek to beginning of next block. This saves us
703 * from shuffling blocks around in the buffer. Take a
704 * look at this from an efficiency stand point later, but
705 * it should only happen once at the end of each job.
707 * I've been lseek()ing negative relative to SEEK_CUR for 30
708 * years now. However, it seems that with the new off_t definition,
709 * it is not possible to seek negative amounts, so we use two
710 * lseek(). One to get the position, then the second to do an
711 * absolute positioning -- so much for efficiency. KES Sep 02.
713 Dmsg0(250, "At end of read block\n");
714 if (block->read_len > block->block_len && !dev->is_tape()) {
716 boffset_t pos = dev->lseek(dcr, (boffset_t)0, SEEK_CUR); /* get curr pos */
717 Dmsg1(250, "Current lseek pos=%s\n", edit_int64(pos, ed1));
718 pos -= (block->read_len - block->block_len);
719 dev->lseek(dcr, pos, SEEK_SET);
720 Dmsg3(250, "Did lseek pos=%s blk_size=%d rdlen=%d\n",
721 edit_int64(pos, ed1), block->block_len,
723 dev->file_addr = pos;
724 dev->file_size = pos;
726 Dmsg3(150, "Exit read_block read_len=%d block_len=%d binbuf=%d\n",
727 block->read_len, block->block_len, block->binbuf);
728 block->block_read = true;