]> git.sur5r.net Git - bacula/bacula/blob - bacula/src/stored/block.c
Change copyright as per agreement with FSFE
[bacula/bacula] / bacula / src / stored / block.c
1 /*
2    Bacula(R) - The Network Backup Solution
3
4    Copyright (C) 2000-2016 Kern Sibbald
5
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.
8
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.
13
14    This notice must be preserved when any source code is 
15    conveyed and/or propagated.
16
17    Bacula(R) is a registered trademark of Kern Sibbald.
18 */
19 /*
20  *
21  *   block.c -- tape block handling functions
22  *
23  *              Kern Sibbald, March MMI
24  *                 added BB02 format October MMII
25  *
26  */
27
28
29 #include "bacula.h"
30 #include "stored.h"
31
32 #ifdef DEBUG_BLOCK_CHECKSUM
33 static const bool debug_block_checksum = true;
34 #else
35 static const bool debug_block_checksum = false;
36 #endif
37
38 #ifdef NO_TAPE_WRITE_TEST
39 static const bool no_tape_write_test = true;
40 #else
41 static const bool no_tape_write_test = false;
42 #endif
43
44
45 bool do_new_file_bookkeeping(DCR *dcr);
46 //bool do_dvd_size_checks(DCR *dcr);
47 void reread_last_block(DCR *dcr);
48 uint32_t get_len_and_clear_block(DEV_BLOCK *block, DEVICE *dev, uint32_t &pad);
49 uint32_t ser_block_header(DEV_BLOCK *block, bool do_checksum);
50 bool unser_block_header(JCR *jcr, DEVICE *dev, DEV_BLOCK *block);
51
52 /*
53  * Write a block to the device, with locking and unlocking
54  *
55  * Returns: true  on success
56  *        : false on failure
57  *
58  */
59 bool DCR::write_block_to_device(bool final)
60 {
61    bool ok = true;
62    DCR *dcr = this;
63
64    if (dcr->spooling) {
65       Dmsg0(200, "Write to spool\n");
66       ok = write_block_to_spool_file(dcr);
67       return ok;
68    }
69
70    if (!is_dev_locked()) {        /* device already locked? */
71       /* note, do not change this to dcr->rLock */
72       dev->rLock(false);          /* no, lock it */
73    }
74
75    if (!check_for_newvol_or_newfile(dcr)) {
76       ok = false;
77       goto bail_out;   /* fatal error */
78    }
79
80    Dmsg1(500, "Write block to dev=%p\n", dcr->dev);
81    if (!write_block_to_dev()) {
82       Dmsg1(40, "*** Failed write_block_to_dev block=%p\n", block);
83       if (job_canceled(jcr) || jcr->getJobType() == JT_SYSTEM) {
84          ok = false;
85          Dmsg2(40, "cancel=%d or SYSTEM=%d\n", job_canceled(jcr),
86             jcr->getJobType() == JT_SYSTEM);
87       } else {
88          ok = fixup_device_block_write_error(dcr);
89       }
90    }
91    if (ok && final && !dir_create_jobmedia_record(dcr)) {
92       Jmsg(jcr, M_FATAL, 0, _("Error writing final JobMedia record to catalog.\n"));
93    }
94
95 bail_out:
96    if (!dcr->is_dev_locked()) {        /* did we lock dev above? */
97       /* note, do not change this to dcr->dunlock */
98       dev->Unlock();                  /* unlock it now */
99    }
100    return ok;
101 }
102
103 /*
104  * Write a block to the device
105  *
106  *  Returns: true  on success or EOT
107  *           false on hard error
108  */
109 bool DCR::write_block_to_dev()
110 {
111    ssize_t stat = 0;
112    uint32_t wlen;                     /* length to write */
113    bool ok = true;
114    DCR *dcr = this;
115    uint32_t checksum;
116    uint32_t pad;                      /* padding or zeros written */
117
118    if (no_tape_write_test) {
119       empty_block(block);
120       return true;
121    }
122    if (job_canceled(jcr)) {
123       return false;
124    }
125
126    Dmsg3(200, "fd=%d bufp-buf=%d binbuf=%d\n", dev->fd(),
127       block->bufp-block->buf, block->binbuf);
128    ASSERT2(block->binbuf == ((uint32_t)(block->bufp - block->buf)), "binbuf badly set");
129
130    if (is_block_empty(block)) {  /* Does block have data in it? */
131       Dmsg0(150, "return write_block_to_dev no data to write\n");
132       return true;
133    }
134
135    dump_block(block, "before write");
136    if (dev->at_weot()) {
137       Dmsg0(50, "==== FATAL: At EOM with ST_WEOT.\n");
138       dev->dev_errno = ENOSPC;
139       Jmsg1(jcr, M_FATAL, 0,  _("Cannot write block. Device at EOM. dev=%s\n"), dev->print_name());
140       return false;
141    }
142    if (!dev->can_append()) {
143       dev->dev_errno = EIO;
144       Jmsg1(jcr, M_FATAL, 0, _("Attempt to write on read-only Volume. dev=%s\n"), dev->print_name());
145       Dmsg1(50, "Attempt to write on read-only Volume. dev=%s\n", dev->print_name());
146       return false;
147    }
148
149    if (!dev->is_open()) {
150       Jmsg1(jcr, M_FATAL, 0, _("Attempt to write on closed device=%s\n"), dev->print_name());
151       Dmsg1(50, "Attempt to write on closed device=%s\n", dev->print_name());
152       return false;
153    }
154
155    wlen = get_len_and_clear_block(block, dev, pad);
156    block->block_len = wlen;
157
158    checksum = ser_block_header(block, dev->do_checksum());
159
160    if (user_volume_size_reached(dcr, true)) {
161       Dmsg0(40, "Calling terminate_writing_volume\n");
162       terminate_writing_volume(dcr);
163       reread_last_block(dcr);   /* Only used on tapes */
164       dev->dev_errno = ENOSPC;
165       return false;
166    }
167
168    /*
169     * Limit maximum File size on volume to user specified value.
170     *  In practical terms, this means to put an EOF mark on
171     *  a tape after every X bytes. This effectively determines
172     *  how many index records we have (JobMedia). If you set
173     *  max_file_size too small, it will cause a lot of shoe-shine
174     *  on very fast modern tape (LTO-3 and above).
175     */
176    if ((dev->max_file_size > 0) &&
177        (dev->file_size+block->binbuf) >= dev->max_file_size) {
178       dev->file_size = 0;             /* reset file size */
179
180       if (!dev->weof(1)) {            /* write eof */
181          Dmsg0(50, "WEOF error in max file size.\n");
182          Jmsg(jcr, M_FATAL, 0, _("Unable to write EOF. ERR=%s\n"),
183             dev->bstrerror());
184          Dmsg0(40, "Calling terminate_writing_volume\n");
185          terminate_writing_volume(dcr);
186          dev->dev_errno = ENOSPC;
187          return false;
188       }
189       if (!write_ansi_ibm_labels(dcr, ANSI_EOF_LABEL, dev->VolHdr.VolumeName)) {
190          return false;
191       }
192
193       if (!do_new_file_bookkeeping(dcr)) {
194          /* Error message already sent */
195          return false;
196       }
197    }
198
199    dev->updateVolCatWrites(1);
200
201 #ifdef DEBUG_BLOCK_ZEROING
202    uint32_t *bp = (uint32_t *)block->buf;
203    if (bp[0] == 0 && bp[1] == 0 && bp[2] == 0 && block->buf[12] == 0) {
204       Jmsg0(jcr, M_ABORT, 0, _("Write block header zeroed.\n"));
205    }
206 #endif
207
208    /*
209     * Do write here, make a somewhat feeble attempt to recover from
210     *  I/O errors, or from the OS telling us it is busy.
211     */
212    int retry = 0;
213    errno = 0;
214    stat = 0;
215    do {
216       if (retry > 0 && stat == -1 && errno == EBUSY) {
217          berrno be;
218          Dmsg4(100, "===== write retry=%d stat=%d errno=%d: ERR=%s\n",
219                retry, stat, errno, be.bstrerror());
220          bmicrosleep(5, 0);    /* pause a bit if busy or lots of errors */
221          dev->clrerror(-1);
222       }
223       stat = dev->write(block->buf, (size_t)wlen);
224       Dmsg4(110, "Write() BlockAddr=%lld NextAddr=%lld Vol=%s wlen=%d\n",
225          block->BlockAddr, dev->lseek(dcr, 0, SEEK_CUR),
226          dev->VolHdr.VolumeName, wlen);
227    } while (stat == -1 && (errno == EBUSY || errno == EIO) && retry++ < 3);
228
229    if (debug_block_checksum) {
230       uint32_t achecksum = ser_block_header(block, dev->do_checksum());
231       if (checksum != achecksum) {
232          Jmsg2(jcr, M_ERROR, 0, _("Block checksum changed during write: before=%u after=%u\n"),
233             checksum, achecksum);
234          dump_block(block, "with checksum error");
235       }
236    }
237
238 #ifdef DEBUG_BLOCK_ZEROING
239    if (bp[0] == 0 && bp[1] == 0 && bp[2] == 0 && block->buf[12] == 0) {
240       Jmsg0(jcr, M_ABORT, 0, _("Write block header zeroed.\n"));
241    }
242 #endif
243
244    if (stat != (ssize_t)wlen) {
245       /* Some devices simply report EIO when the volume is full.
246        * With a little more thought we may be able to check
247        * capacity and distinguish real errors and EOT
248        * conditions.  In any case, we probably want to
249        * simulate an End of Medium.
250        */
251       if (stat == -1) {
252          berrno be;
253          dev->clrerror(-1);                 /* saves errno in dev->dev_errno */
254          if (dev->dev_errno == 0) {
255             dev->dev_errno = ENOSPC;        /* out of space */
256          }
257          if (dev->dev_errno != ENOSPC) {
258             dev->VolCatInfo.VolCatErrors++;
259             Jmsg4(jcr, M_ERROR, 0, _("Write error at %u:%u on device %s. ERR=%s.\n"),
260                dev->file, dev->block_num, dev->print_name(), be.bstrerror());
261          }
262       } else {
263         dev->dev_errno = ENOSPC;            /* out of space */
264       }
265       if (dev->dev_errno == ENOSPC) {
266          dev->update_freespace();
267          if (dev->is_freespace_ok() && dev->free_space < dev->min_free_space) {
268             dev->set_nospace();
269             Jmsg(jcr, M_WARNING, 0, _("Out of freespace caused End of Volume \"%s\" at %u:%u on device %s. Write of %u bytes got %d.\n"),
270                dev->getVolCatName(),
271                dev->file, dev->block_num, dev->print_name(), wlen, stat);
272          } else {
273             dev->clear_nospace();
274             Jmsg(jcr, M_INFO, 0, _("End of Volume \"%s\" at %u:%u on device %s. Write of %u bytes got %d.\n"),
275                dev->getVolCatName(),
276                dev->file, dev->block_num, dev->print_name(), wlen, stat);
277          }
278       }
279       if (chk_dbglvl(100)) {
280          berrno be;
281          Dmsg7(90, "==== Write error. fd=%d size=%u rtn=%d dev_blk=%d blk_blk=%d errno=%d: ERR=%s\n",
282             dev->fd(), wlen, stat, dev->block_num, block->BlockNumber,
283             dev->dev_errno, be.bstrerror(dev->dev_errno));
284       }
285
286       Dmsg0(40, "Calling terminate_writing_volume\n");
287       ok = terminate_writing_volume(dcr);
288       if (ok) {
289          reread_last_block(dcr);
290       }
291       return false;
292    }
293
294    /* We successfully wrote the block, now do housekeeping */
295    Dmsg2(1300, "VolCatBytes=%lld newVolCatBytes=%lld\n", dev->VolCatInfo.VolCatBytes,
296       (dev->VolCatInfo.VolCatBytes+wlen));
297    dev->updateVolCatBytes(wlen);
298    dev->updateVolCatBlocks(1);
299    dev->EndBlock = dev->block_num;
300    dev->EndFile  = dev->file;
301    dev->LastBlock = block->BlockNumber;
302    block->BlockNumber++;
303
304    /* Update dcr values */
305    if (dev->is_tape()) {
306       if (dcr->EndFile != dev->EndFile || dev->EndBlock > dcr->EndBlock) {
307          dcr->EndBlock = dev->EndBlock;
308          dcr->EndFile  = dev->EndFile;
309       }
310       dev->block_num++;
311    } else {
312       /* Save address of block just written */
313       uint64_t addr = dev->file_addr + wlen - 1;
314       if (dcr->EndFile == (uint32_t)(addr >> 32) &&
315           (uint32_t)addr < dcr->EndBlock) {
316          Pmsg4(000, "Possible incorrect EndBlock oldEndBlock=%u newEndBlock=%u oldEndFile=%u newEndFile=%u\n",
317             dcr->EndBlock, (uint32_t)addr, dcr->EndFile, (uint32_t)(addr >> 32));
318       } else {
319          dcr->EndBlock = (uint32_t)addr;
320          dcr->EndFile = (uint32_t)(addr >> 32);
321       }
322       dev->block_num = (uint32_t)addr;
323       dev->file = (uint32_t)(addr >> 32);
324       block->BlockAddr = dev->file_addr + wlen;
325       Dmsg3(150, "Set block->BlockAddr=%lld wlen=%d block=%x\n",
326          block->BlockAddr, wlen, block);
327    }
328    dcr->VolMediaId = dev->VolCatInfo.VolMediaId;
329    Dmsg3(150, "VolFirstIndex=%d blockFirstIndex=%d Vol=%s\n",
330       dcr->VolFirstIndex, block->FirstIndex, dcr->VolumeName);
331    if (dcr->VolFirstIndex == 0 && block->FirstIndex > 0) {
332       dcr->VolFirstIndex = block->FirstIndex;
333    }
334    if (block->LastIndex > (int32_t)dcr->VolLastIndex) {
335       dcr->VolLastIndex = block->LastIndex;
336    }
337    dcr->WroteVol = true;
338    dev->file_addr += wlen;            /* update file address */
339    dev->file_size += wlen;
340    dev->part_size += wlen;
341    dev->setVolCatInfo(false);         /* Needs update */
342
343    Dmsg2(1300, "write_block: wrote block %d bytes=%d\n", dev->block_num, wlen);
344    empty_block(block);
345    return true;
346 }
347
348
349 /*
350  * Read block with locking
351  *
352  */
353 bool DCR::read_block_from_device(bool check_block_numbers)
354 {
355    bool ok;
356
357    Dmsg0(250, "Enter read_block_from_device\n");
358    dev->rLock(false);
359    ok = read_block_from_dev(check_block_numbers);
360    dev->rUnlock();
361    Dmsg0(250, "Leave read_block_from_device\n");
362    return ok;
363 }
364
365 static void set_block_position(DCR *dcr, DEVICE *dev, DEV_BLOCK *block)
366 {
367    if (dev->is_tape()) {
368       block->Block = dev->block_num;
369       block->File = dev->file;
370    } else {
371       block->Block = (uint32_t)dev->file_addr;
372       block->File  = (uint32_t)(dev->file_addr >> 32);
373    }
374    block->RecNum = 0;
375 }
376
377 /*
378  * Read the next block into the block structure and unserialize
379  *  the block header.  For a file, the block may be partially
380  *  or completely in the current buffer.
381  */
382 bool DCR::read_block_from_dev(bool check_block_numbers)
383 {
384    ssize_t stat;
385    int looping;
386    int retry;
387    DCR *dcr = this;
388
389    if (job_canceled(jcr)) {
390       Mmsg(dev->errmsg, _("Job failed or canceled.\n"));
391       block->read_len = 0;
392       return false;
393    }
394
395    if (dev->at_eot()) {
396       Mmsg(dev->errmsg, _("Attempt to read past end of tape or file.\n"));
397       block->read_len = 0;
398       return false;
399    }
400    looping = 0;
401    Dmsg1(250, "Full read in read_block_from_device() len=%d\n", block->buf_len);
402
403    if (!dev->is_open()) {
404       Mmsg4(dev->errmsg, _("Attempt to read closed device: fd=%d at file:blk %u:%u on device %s\n"),
405          dev->fd(), dev->file, dev->block_num, dev->print_name());
406       Jmsg(dcr->jcr, M_FATAL, 0, "%s", dev->errmsg);
407       Pmsg1(000, "%s", dev->errmsg);
408       block->read_len = 0;
409       return false;
410    }
411
412    set_block_position(dcr, dev, block);
413
414 reread:
415    if (looping > 1) {
416       dev->dev_errno = EIO;
417       Mmsg1(dev->errmsg, _("Block buffer size looping problem on device %s\n"),
418          dev->print_name());
419       Jmsg(jcr, M_ERROR, 0, "%s", dev->errmsg);
420       block->read_len = 0;
421       return false;
422    }
423
424    dump_block(block, "before read");
425
426 #ifdef xxxBUILD_DVD
427    /* Check for DVD part file end */
428    if (dev->at_eof() && dev->is_dvd() && dev->num_dvd_parts > 0 &&
429         dev->part <= dev->num_dvd_parts) {
430       Dmsg0(400, "Call dvd_open_next_part\n");
431       if (dvd_open_next_part(dcr) < 0) {
432          Mmsg3(dev->errmsg, _("Unable to open device part=%d %s: ERR=%s\n"),
433                dev->part, dev->print_name(), dev->bstrerror());
434          Jmsg(dcr->jcr, M_FATAL, 0, "%s", dev->errmsg);
435          dev->dev_errno = EIO;
436          return false;
437       }
438    }
439 #endif /* xxxBUILD_DVD */
440
441    retry = 0;
442    errno = 0;
443    stat = 0;
444
445    boffset_t pos = dev->lseek(dcr, (boffset_t)0, SEEK_CUR); /* get curr pos */
446    do {
447       if ((retry > 0 && stat == -1 && errno == EBUSY)) {
448          berrno be;
449          Dmsg4(100, "===== read retry=%d stat=%d errno=%d: ERR=%s\n",
450                retry, stat, errno, be.bstrerror());
451          bmicrosleep(10, 0);    /* pause a bit if busy or lots of errors */
452          dev->clrerror(-1);
453       }
454       stat = dev->read(block->buf, (size_t)block->buf_len);
455
456    } while (stat == -1 && (errno == EBUSY || errno == EINTR || errno == EIO) && retry++ < 3);
457    Dmsg3(110, "Read() vol=%s nbytes=%d addr=%lld\n",
458       dev->VolHdr.VolumeName, stat, pos);
459    if (stat < 0) {
460       berrno be;
461       dev->clrerror(-1);
462       Dmsg2(90, "Read device fd=%d got: ERR=%s\n", dev->fd(), be.bstrerror());
463       block->read_len = 0;
464       if (dev->file == 0 && dev->block_num == 0) { /* Attempt to read label */
465          Mmsg(dev->errmsg, _("The Volume=%s on device=%s appears to be unlabeled.\n"),
466             "", dev->VolCatInfo.VolCatName, dev->print_name());
467       } else {
468          Mmsg5(dev->errmsg, _("Read error on fd=%d at file:blk %u:%u on device %s. ERR=%s.\n"),
469             dev->fd(), dev->file, dev->block_num, dev->print_name(), be.bstrerror());
470       }
471       Jmsg(jcr, M_ERROR, 0, "%s", dev->errmsg);
472       if (dev->at_eof()) {        /* EOF just seen? */
473          dev->set_eot();          /* yes, error => EOT */
474       }
475       return false;
476    }
477    if (stat == 0) {             /* Got EOF ! */
478       if (dev->file == 0 && dev->block_num == 0) { /* Attempt to read label */
479          Mmsg3(dev->errmsg, _("The %sVolume=%s on device=%s appears to be unlabeled.\n"),
480             "", dev->VolCatInfo.VolCatName, dev->print_name());
481       } else {
482          Mmsg4(dev->errmsg, _("Read zero %sbytes Vol=%s at %lld on device %s.\n"),
483                "", dev->VolCatInfo.VolCatName, pos, dev->print_name());
484       }
485       dev->block_num = 0;
486       block->read_len = 0;
487       Dmsg1(100, "%s", dev->errmsg);
488       if (dev->at_eof()) {       /* EOF already read? */
489          dev->set_eot();         /* yes, 2 EOFs => EOT */
490          return false;
491       }
492       dev->set_ateof();
493       Dmsg2(150, "==== Read zero bytes. vol=%s at %lld\n", dev->VolCatInfo.VolCatName, pos);
494       return false;             /* return eof */
495    }
496
497    /* Continue here for successful read */
498
499    block->read_len = stat;      /* save length read */
500    if (block->read_len == 80 &&
501         (dcr->VolCatInfo.LabelType != B_BACULA_LABEL ||
502          dcr->device->label_type != B_BACULA_LABEL)) {
503       /* ***FIXME*** should check label */
504       Dmsg2(100, "Ignore 80 byte ANSI label at %u:%u\n", dev->file, dev->block_num);
505       dev->clear_eof();
506       goto reread;             /* skip ANSI/IBM label */
507    }
508
509    if (block->read_len < BLKHDR2_LENGTH) {
510       dev->dev_errno = EIO;
511       Mmsg4(dev->errmsg, _("Volume data error at %u:%u! Very short block of %d bytes on device %s discarded.\n"),
512          dev->file, dev->block_num, block->read_len, dev->print_name());
513       Jmsg(jcr, M_ERROR, 0, "%s", dev->errmsg);
514       dev->set_short_block();
515       block->read_len = block->binbuf = 0;
516       Dmsg2(50, "set block=%p binbuf=%d\n", block, block->binbuf);
517       return false;             /* return error */
518    }
519
520    //BlockNumber = block->BlockNumber + 1;
521    if (!unser_block_header(jcr, dev, block)) {
522       if (forge_on) {
523          dev->file_addr += block->read_len;
524          dev->file_size += block->read_len;
525          goto reread;
526       }
527       return false;
528    }
529
530    /*
531     * If the block is bigger than the buffer, we reposition for
532     *  re-reading the block, allocate a buffer of the correct size,
533     *  and go re-read.
534     */
535    Dmsg2(150, "block_len=%d buf_len=%d\n", block->block_len, block->buf_len);
536    if (block->block_len > block->buf_len) {
537       dev->dev_errno = EIO;
538       Mmsg2(dev->errmsg,  _("Block length %u is greater than buffer %u. Attempting recovery.\n"),
539          block->block_len, block->buf_len);
540       Jmsg(jcr, M_ERROR, 0, "%s", dev->errmsg);
541       Pmsg1(000, "%s", dev->errmsg);
542       /* Attempt to reposition to re-read the block */
543       if (dev->is_tape()) {
544          Dmsg0(250, "BSR for reread; block too big for buffer.\n");
545          if (!dev->bsr(1)) {
546             Mmsg(dev->errmsg, "%s", dev->bstrerror());
547             Jmsg(jcr, M_ERROR, 0, "%s", dev->errmsg);
548             block->read_len = 0;
549             return false;
550          }
551       } else {
552          Dmsg0(250, "Seek to beginning of block for reread.\n");
553          boffset_t pos = dev->lseek(dcr, (boffset_t)0, SEEK_CUR); /* get curr pos */
554          pos -= block->read_len;
555          dev->lseek(dcr, pos, SEEK_SET);
556          dev->file_addr = pos;
557       }
558       Mmsg1(dev->errmsg, _("Setting block buffer size to %u bytes.\n"), block->block_len);
559       Jmsg(jcr, M_INFO, 0, "%s", dev->errmsg);
560       Pmsg1(000, "%s", dev->errmsg);
561       /* Set new block length */
562       dev->max_block_size = block->block_len;
563       block->buf_len = block->block_len;
564       free_memory(block->buf);
565       block->buf = get_memory(block->buf_len);
566       empty_block(block);
567       looping++;
568       goto reread;                    /* re-read block with correct block size */
569    }
570
571    if (block->block_len > block->read_len) {
572       dev->dev_errno = EIO;
573       Mmsg4(dev->errmsg, _("Volume data error at %u:%u! Short block of %d bytes on device %s discarded.\n"),
574          dev->file, dev->block_num, block->read_len, dev->print_name());
575       Jmsg(jcr, M_ERROR, 0, "%s", dev->errmsg);
576       dev->set_short_block();
577       block->read_len = block->binbuf = 0;
578       return false;             /* return error */
579    }
580
581    dev->clear_short_block();
582    dev->clear_eof();
583    dev->updateVolCatReads(1);
584    dev->updateVolCatReadBytes(block->read_len);
585
586    dev->EndBlock = dev->block_num;
587    dev->EndFile  = dev->file;
588    dev->block_num++;
589
590    /* Update dcr values */
591    if (dev->is_tape()) {
592       if (dcr->EndFile != dev->EndFile || dev->EndBlock > dcr->EndBlock) {
593          dcr->EndBlock = dev->EndBlock;
594          dcr->EndFile  = dev->EndFile;
595       }
596    } else {
597       /* We need to take care about a short block in EndBlock/File
598        * computation
599        */
600       uint32_t len = MIN(block->read_len, block->block_len);
601       uint64_t addr = dev->file_addr + len - 1;
602       if ((uint32_t)(addr >> 32) != dcr->EndFile || (uint32_t)addr > dcr->EndBlock) {
603          dcr->EndBlock = (uint32_t)addr;
604          dcr->EndFile = (uint32_t)(addr >> 32);
605       }
606       dev->block_num = dev->EndBlock = (uint32_t)addr;
607       dev->file = dev->EndFile = (uint32_t)(addr >> 32);
608    }
609    dcr->VolMediaId = dev->VolCatInfo.VolMediaId;
610    dev->file_addr += block->read_len;
611    dev->file_size += block->read_len;
612
613    /*
614     * If we read a short block on disk,
615     * seek to beginning of next block. This saves us
616     * from shuffling blocks around in the buffer. Take a
617     * look at this from an efficiency stand point later, but
618     * it should only happen once at the end of each job.
619     *
620     * I've been lseek()ing negative relative to SEEK_CUR for 30
621     *   years now. However, it seems that with the new off_t definition,
622     *   it is not possible to seek negative amounts, so we use two
623     *   lseek(). One to get the position, then the second to do an
624     *   absolute positioning -- so much for efficiency.  KES Sep 02.
625     */
626    Dmsg0(250, "At end of read block\n");
627    if (block->read_len > block->block_len && !dev->is_tape()) {
628       char ed1[50];
629       boffset_t pos = dev->lseek(dcr, (boffset_t)0, SEEK_CUR); /* get curr pos */
630       Dmsg1(250, "Current lseek pos=%s\n", edit_int64(pos, ed1));
631       pos -= (block->read_len - block->block_len);
632       dev->lseek(dcr, pos, SEEK_SET);
633       Dmsg3(250, "Did lseek pos=%s blk_size=%d rdlen=%d\n",
634          edit_int64(pos, ed1), block->block_len,
635             block->read_len);
636       dev->file_addr = pos;
637       dev->file_size = pos;
638    }
639    Dmsg3(150, "Exit read_block read_len=%d block_len=%d binbuf=%d\n",
640       block->read_len, block->block_len, block->binbuf);
641    block->block_read = true;
642    return true;
643 }