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