]> git.sur5r.net Git - bacula/bacula/blob - bacula/patches/testing/bsr_addr.patch
ebl Too many external segfault in this way
[bacula/bacula] / bacula / patches / testing / bsr_addr.patch
1 Index: src/dird/bsr.c
2 ===================================================================
3 --- src/dird/bsr.c      (révision 8163)
4 +++ src/dird/bsr.c      (copie de travail)
5 @@ -325,6 +325,7 @@
6   */
7  static uint32_t write_bsr(UAContext *ua, RESTORE_CTX &rx, FILE *fd)
8  {
9 +   char ed1[50], ed2[50];
10     uint32_t count = 0;
11     uint32_t total_count = 0;
12     uint32_t LastIndex = 0;
13 @@ -362,18 +363,20 @@
14              }
15              fprintf(fd, "VolSessionId=%u\n", bsr->VolSessionId);
16              fprintf(fd, "VolSessionTime=%u\n", bsr->VolSessionTime);
17 -            if (bsr->VolParams[i].StartFile == bsr->VolParams[i].EndFile) {
18 -               fprintf(fd, "VolFile=%u\n", bsr->VolParams[i].StartFile);
19 -            } else {
20 -               fprintf(fd, "VolFile=%u-%u\n", bsr->VolParams[i].StartFile,
21 -                       bsr->VolParams[i].EndFile);
22 -            }
23 -            if (bsr->VolParams[i].StartBlock == bsr->VolParams[i].EndBlock) {
24 -               fprintf(fd, "VolBlock=%u\n", bsr->VolParams[i].StartBlock);
25 -            } else {
26 -               fprintf(fd, "VolBlock=%u-%u\n", bsr->VolParams[i].StartBlock,
27 -                       bsr->VolParams[i].EndBlock);
28 -            }
29 +//            if (bsr->VolParams[i].StartFile == bsr->VolParams[i].EndFile) {
30 +//               fprintf(fd, "VolFile=%u\n", bsr->VolParams[i].StartFile);
31 +//            } else {
32 +//               fprintf(fd, "VolFile=%u-%u\n", bsr->VolParams[i].StartFile,
33 +//                       bsr->VolParams[i].EndFile);
34 +//            }
35 +//            if (bsr->VolParams[i].StartBlock == bsr->VolParams[i].EndBlock) {
36 +//               fprintf(fd, "VolBlock=%u\n", bsr->VolParams[i].StartBlock);
37 +//            } else {
38 +//               fprintf(fd, "VolBlock=%u-%u\n", bsr->VolParams[i].StartBlock,
39 +//                       bsr->VolParams[i].EndBlock);
40 +//            }
41 +            fprintf(fd, "VolAddr=%s-%s\n", edit_uint64(bsr->VolParams[i].StartAddr, ed1),
42 +                    edit_uint64(bsr->VolParams[i].EndAddr, ed2));
43     //       Dmsg2(100, "bsr VolParam FI=%u LI=%u\n",
44     //          bsr->VolParams[i].FirstIndex, bsr->VolParams[i].LastIndex);
45  
46 @@ -428,18 +431,20 @@
47              }
48              fprintf(fd, "VolSessionId=%u\n", bsr->VolSessionId);
49              fprintf(fd, "VolSessionTime=%u\n", bsr->VolSessionTime);
50 -            if (bsr->VolParams[i].StartFile == bsr->VolParams[i].EndFile) {
51 -               fprintf(fd, "VolFile=%u\n", bsr->VolParams[i].StartFile);
52 -            } else {
53 -               fprintf(fd, "VolFile=%u-%u\n", bsr->VolParams[i].StartFile,
54 -                       bsr->VolParams[i].EndFile);
55 -            }
56 -            if (bsr->VolParams[i].StartBlock == bsr->VolParams[i].EndBlock) {
57 -               fprintf(fd, "VolBlock=%u\n", bsr->VolParams[i].StartBlock);
58 -            } else {
59 -               fprintf(fd, "VolBlock=%u-%u\n", bsr->VolParams[i].StartBlock,
60 -                       bsr->VolParams[i].EndBlock);
61 -            }
62 +//            if (bsr->VolParams[i].StartFile == bsr->VolParams[i].EndFile) {
63 +//               fprintf(fd, "VolFile=%u\n", bsr->VolParams[i].StartFile);
64 +//            } else {
65 +//               fprintf(fd, "VolFile=%u-%u\n", bsr->VolParams[i].StartFile,
66 +//                       bsr->VolParams[i].EndFile);
67 +//            }
68 +//            if (bsr->VolParams[i].StartBlock == bsr->VolParams[i].EndBlock) {
69 +//               fprintf(fd, "VolBlock=%u\n", bsr->VolParams[i].StartBlock);
70 +//            } else {
71 +//               fprintf(fd, "VolBlock=%u-%u\n", bsr->VolParams[i].StartBlock,
72 +//                       bsr->VolParams[i].EndBlock);
73 +//            }
74 +            fprintf(fd, "VolAddr=%s-%s\n", edit_uint64(bsr->VolParams[i].StartAddr, ed1),
75 +                    edit_uint64(bsr->VolParams[i].EndAddr, ed2));
76     //       Dmsg2(100, "bsr VolParam FI=%u LI=%u\n",
77     //          bsr->VolParams[i].FirstIndex, bsr->VolParams[i].LastIndex);
78  
79 Index: src/cats/cats.h
80 ===================================================================
81 --- src/cats/cats.h     (révision 8163)
82 +++ src/cats/cats.h     (copie de travail)
83 @@ -844,6 +844,8 @@
84     uint32_t StartBlock;               /* start block on tape */
85     uint32_t EndBlock;                 /* last block */
86     int32_t Slot;                      /* Slot */
87 +   uint64_t StartAddr;                /* Start address */
88 +   uint64_t EndAddr;                  /* End address */
89  // uint32_t Copy;                     /* identical copy */
90  // uint32_t Stripe;                   /* RAIT strip number */
91  };
92 Index: src/cats/sql_get.c
93 ===================================================================
94 --- src/cats/sql_get.c  (révision 8163)
95 +++ src/cats/sql_get.c  (copie de travail)
96 @@ -463,6 +463,8 @@
97                 Vols[i].EndFile = str_to_uint64(row[5]);
98                 Vols[i].StartBlock = str_to_uint64(row[6]);
99                 Vols[i].EndBlock = str_to_uint64(row[7]);
100 +               Vols[i].StartAddr = (((uint64_t)Vols[i].StartFile)<<32) | Vols[i].StartBlock;
101 +               Vols[i].EndAddr =   (((uint64_t)Vols[i].EndFile)<<32) | Vols[i].EndBlock;
102  //             Vols[i].Copy = str_to_uint64(row[8]);
103                 Vols[i].Slot = str_to_uint64(row[9]);
104                 StorageId = str_to_uint64(row[10]);
105 Index: src/stored/match_bsr.c
106 ===================================================================
107 --- src/stored/match_bsr.c      (révision 8174)
108 +++ src/stored/match_bsr.c      (copie de travail)
109 @@ -36,15 +36,6 @@
110  
111  /*
112   * ***FIXME***
113 - * find_smallest_volfile needs to be fixed to only look at items that
114 - *   are not marked as done.  Otherwise, it can find a bsr
115 - *   that has already been consumed, and this will cause the
116 - *   bsr to be used, thus we may seek back and re-read the
117 - *   same records, causing an error.  This deficiency must
118 - *   be fixed.  For the moment, it has been kludged in 
119 - *   read_record.c to avoid seeking back if find_next_bsr
120 - *   returns a bsr pointing to a smaller address (file/block).
121 - *
122   * Also for efficiency, once a bsr is done, it really should be
123   *   delinked from the bsr chain.  This will avoid the above 
124   *   problem and make traversal of the bsr chain more efficient.
125 @@ -73,7 +64,7 @@
126  static int match_jobid(BSR *bsr, BSR_JOBID *jobid, SESSION_LABEL *sessrec, bool done);
127  static int match_findex(BSR *bsr, BSR_FINDEX *findex, DEV_RECORD *rec, bool done);
128  static int match_volfile(BSR *bsr, BSR_VOLFILE *volfile, DEV_RECORD *rec, bool done);
129 -static int match_volblock(BSR *bsr, BSR_VOLBLOCK *volblock, DEV_RECORD *rec, bool done);
130 +static int match_voladdr(BSR *bsr, BSR_VOLADDR *voladdr, DEV_RECORD *rec, bool done);
131  static int match_stream(BSR *bsr, BSR_STREAM *stream, DEV_RECORD *rec, bool done);
132  static int match_all(BSR *bsr, DEV_RECORD *rec, VOLUME_LABEL *volrec, SESSION_LABEL *sessrec, bool done, JCR *jcr);
133  static int match_block_sesstime(BSR *bsr, BSR_SESSTIME *sesstime, DEV_BLOCK *block);
134 @@ -255,7 +246,29 @@
135  }
136  
137  /*
138 - * ***FIXME***
139 + * Get the smallest address from this voladdr part
140 + * Don't use "done" elements
141 + */
142 +static bool get_smallest_voladdr(BSR_VOLADDR *va, uint64_t *ret)
143 +{
144 +   bool ok=false;
145 +   uint64_t min_val=0;
146 +
147 +   for (; va ; va = va->next) {
148 +      if (!va->done) {
149 +         if (ok) {
150 +            min_val = MIN(min_val, va->saddr);
151 +         } else {
152 +            min_val = va->saddr;
153 +            ok=true;
154 +         }
155 +      }
156 +   }
157 +   *ret = min_val;
158 +   return ok;
159 +}
160 +
161 +/* FIXME
162   * This routine needs to be fixed to only look at items that
163   *   are not marked as done.  Otherwise, it can find a bsr
164   *   that has already been consumed, and this will cause the
165 @@ -264,6 +277,7 @@
166   *   be fixed.  For the moment, it has been kludged in 
167   *   read_record.c to avoid seeking back if find_next_bsr
168   *   returns a bsr pointing to a smaller address (file/block).
169 + *
170   */
171  static BSR *find_smallest_volfile(BSR *found_bsr, BSR *bsr)
172  {
173 @@ -272,7 +286,19 @@
174     BSR_VOLBLOCK *vb;
175     uint32_t found_bsr_sfile, bsr_sfile;
176     uint32_t found_bsr_sblock, bsr_sblock;
177 +   uint64_t found_bsr_saddr, bsr_saddr;
178  
179 +   /* if we have VolAddr, use it, else try with File and Block */
180 +   if (get_smallest_voladdr(found_bsr->voladdr, &found_bsr_saddr)) {
181 +      if (get_smallest_voladdr(bsr->voladdr, &bsr_saddr)) {
182 +         if (found_bsr_saddr > bsr_saddr) {
183 +            return bsr;
184 +         } else {
185 +            return found_bsr;
186 +         }
187 +      }
188 +   }
189 +
190     /* Find the smallest file in the found_bsr */
191     vf = found_bsr->volfile;
192     found_bsr_sfile = vf->sfile;
193 @@ -374,20 +400,20 @@
194              volrec->VolumeName);
195  
196     if (!match_volfile(bsr, bsr->volfile, rec, 1)) {
197 -      Dmsg3(dbglevel, "Fail on file=%u. bsr=%u,%u\n", 
198 -         rec->File, bsr->volfile->sfile, bsr->volfile->efile);
199 +      if (bsr->volfile) {
200 +         Dmsg3(dbglevel, "Fail on file=%u. bsr=%u,%u\n", 
201 +               rec->File, bsr->volfile->sfile, bsr->volfile->efile);
202 +      }
203        goto no_match;
204     }
205 -   Dmsg3(dbglevel, "OK bsr file=%u. bsr=%u,%u\n", 
206 -         rec->File, bsr->volfile->sfile, bsr->volfile->efile);
207  
208 -   if (!match_volblock(bsr, bsr->volblock, rec, 1)) {
209 -      Dmsg3(dbglevel, "Fail on Block=%u. bsr=%u,%u\n", 
210 -         rec->Block, bsr->volblock->sblock, bsr->volblock->eblock);
211 +   if (!match_voladdr(bsr, bsr->voladdr, rec, 1)) {
212 +      if (bsr->voladdr) {
213 +         Dmsg3(dbglevel, "Fail on Addr=%lld. bsr=%lld,%lld\n", 
214 +               get_record_address(rec), bsr->voladdr->saddr, bsr->voladdr->eaddr);
215 +      }
216        goto no_match;
217     }
218 -   Dmsg3(dbglevel, "OK bsr Block=%u. bsr=%u,%u\n", 
219 -      rec->Block, bsr->volblock->sblock, bsr->volblock->eblock);
220  
221     if (!match_sesstime(bsr, bsr->sesstime, rec, 1)) {
222        Dmsg2(dbglevel, "Fail on sesstime. bsr=%u rec=%u\n",
223 @@ -605,42 +631,35 @@
224     return 0;
225  }
226  
227 -static int match_volblock(BSR *bsr, BSR_VOLBLOCK *volblock, DEV_RECORD *rec, bool done)
228 +static int match_voladdr(BSR *bsr, BSR_VOLADDR *voladdr, DEV_RECORD *rec, bool done)
229  {
230 -   /*
231 -    * Currently block matching does not work correctly for disk
232 -    * files in all cases, so it is "turned off" by the following 
233 -    * return statement.
234 -    */
235 -   return 1;
236 -
237 -
238 -   if (!volblock) {
239 +   if (!voladdr) {
240        return 1;                       /* no specification matches all */
241     }
242     /* For the moment, these tests work only with disk. */
243     if (rec->state & REC_ISTAPE) {
244        return 1;                       /* All File records OK for this match */
245     }
246 -//  Dmsg3(dbglevel, "match_volblock: sblock=%u eblock=%u recblock=%u\n",
247 -//             volblock->sblock, volblock->eblock, rec->Block);
248 -   if (volblock->sblock <= rec->Block && volblock->eblock >= rec->Block) {
249 +   uint64_t addr = get_record_address(rec);
250 +//  Dmsg3(dbglevel, "match_voladdr: saddr=%lld eaddr=%lld recaddr=%lld\n",
251 +//             volblock->saddr, volblock->eaddr, addr);
252 +   if (voladdr->saddr <= addr && voladdr->eaddr >= addr) {
253        return 1;
254     }
255     /* Once we get past last eblock, we are done */
256 -   if (rec->Block > volblock->eblock) {
257 -      volblock->done = true;              /* set local done */
258 +   if (addr > voladdr->eaddr) {
259 +      voladdr->done = true;              /* set local done */
260     }
261 -   if (volblock->next) {
262 -      return match_volblock(bsr, volblock->next, rec, volblock->done && done);
263 +   if (voladdr->next) {
264 +      return match_voladdr(bsr, voladdr->next, rec, voladdr->done && done);
265     }
266  
267     /* If we are done and all prior matches are done, this bsr is finished */
268 -   if (volblock->done && done) {
269 +   if (voladdr->done && done) {
270        bsr->done = true;
271        bsr->root->reposition = true;
272 -      Dmsg2(dbglevel, "bsr done from volblock rec=%u voleblock=%u\n",
273 -         rec->Block, volblock->eblock);
274 +      Dmsg2(dbglevel, "bsr done from voladdr rec=%lld voleaddr=%lld\n",
275 +            addr, voladdr->eaddr);
276     }
277     return 0;
278  }
279 @@ -733,3 +752,29 @@
280     }
281     return 0;
282  }
283 +
284 +uint64_t get_bsr_start_addr(BSR *bsr, uint32_t *file, uint32_t *block)
285 +{
286 +   uint64_t bsr_addr = 0;
287 +   uint32_t sfile = 0, sblock = 0;
288 +
289 +   if (bsr) {
290 +      if (bsr->voladdr) {
291 +         bsr_addr = bsr->voladdr->saddr;
292 +         sfile = bsr_addr>>32;
293 +         sblock = (uint32_t)bsr_addr;
294 +         
295 +      } else if (bsr->volfile && bsr->volblock) {
296 +         bsr_addr = (((uint64_t)bsr->volfile->sfile)<<32)|bsr->volblock->sblock;
297 +         sfile = bsr->volfile->sfile;
298 +         sblock = bsr->volblock->sblock;
299 +      }
300 +   }
301 +
302 +   if (file && block) {
303 +      *file = sfile;
304 +      *block = sblock;
305 +   }
306 +
307 +   return bsr_addr;
308 +}
309 Index: src/stored/read_record.c
310 ===================================================================
311 --- src/stored/read_record.c    (révision 8163)
312 +++ src/stored/read_record.c    (copie de travail)
313 @@ -344,19 +344,21 @@
314         *   when find_next_bsr() is fixed not to return a bsr already
315         *   completed.
316         */
317 -      if (dev->file > bsr->volfile->sfile ||             
318 -         (dev->file == bsr->volfile->sfile && dev->block_num > bsr->volblock->sblock)) {
319 +      uint32_t block, file;
320 +      /* TODO: use dev->file_addr ? */
321 +      uint64_t dev_addr = (((uint64_t) dev->file)<<32) | dev->block_num;
322 +      uint64_t bsr_addr = get_bsr_start_addr(bsr, &file, &block);
323 +
324 +      if (dev_addr > bsr_addr) {
325           return false;
326        }
327        if (verbose) {
328 -         Jmsg(jcr, M_INFO, 0, _("Reposition from (file:block) %u:%u to %u:%u\n"),
329 -            dev->file, dev->block_num, bsr->volfile->sfile,
330 -            bsr->volblock->sblock);
331 +         Jmsg(jcr, M_INFO,0, _("Reposition from (file:block) %u:%u to %u:%u\n"),
332 +              dev->file, dev->block_num, file, block);
333        }
334        Dmsg4(10, "Try_Reposition from (file:block) %u:%u to %u:%u\n",
335 -            dev->file, dev->block_num, bsr->volfile->sfile,
336 -            bsr->volblock->sblock);
337 -      dev->reposition(dcr, bsr->volfile->sfile, bsr->volblock->sblock);
338 +            dev->file, dev->block_num, file, block);
339 +      dev->reposition(dcr, file, block);
340        rec->Block = 0;
341     }
342     return false;
343 @@ -369,6 +371,7 @@
344  {
345     BSR *bsr = NULL;
346     DEVICE *dev = dcr->dev;
347 +   uint32_t file, block;
348     /*
349      * Now find and position to first file and block
350      *   on this tape.
351 @@ -376,11 +379,11 @@
352     if (jcr->bsr) {
353        jcr->bsr->reposition = true;    /* force repositioning */
354        bsr = find_next_bsr(jcr->bsr, dev);
355 -      if (bsr && (bsr->volfile->sfile != 0 || bsr->volblock->sblock != 0)) {
356 +      
357 +      if (get_bsr_start_addr(bsr, &file, &block) > 0) {
358           Jmsg(jcr, M_INFO, 0, _("Forward spacing Volume \"%s\" to file:block %u:%u.\n"),
359 -            dev->VolHdr.VolumeName,
360 -            bsr->volfile->sfile, bsr->volblock->sblock);
361 -         dev->reposition(dcr, bsr->volfile->sfile, bsr->volblock->sblock);
362 +              dev->VolHdr.VolumeName, file, block);
363 +         dev->reposition(dcr, file, block);
364        }
365     }
366     return bsr;
367 Index: src/stored/parse_bsr.c
368 ===================================================================
369 --- src/stored/parse_bsr.c      (révision 8163)
370 +++ src/stored/parse_bsr.c      (copie de travail)
371 @@ -52,6 +52,7 @@
372  static BSR *store_sessid(LEX *lc, BSR *bsr);
373  static BSR *store_volfile(LEX *lc, BSR *bsr);
374  static BSR *store_volblock(LEX *lc, BSR *bsr);
375 +static BSR *store_voladdr(LEX *lc, BSR *bsr);
376  static BSR *store_sesstime(LEX *lc, BSR *bsr);
377  static BSR *store_include(LEX *lc, BSR *bsr);
378  static BSR *store_exclude(LEX *lc, BSR *bsr);
379 @@ -85,6 +86,7 @@
380     {"exclude", store_exclude},
381     {"volfile", store_volfile},
382     {"volblock", store_volblock},
383 +   {"voladdr",  store_voladdr},
384     {"stream",   store_stream},
385     {"slot",     store_slot},
386     {"device",   store_device},
387 @@ -212,17 +214,17 @@
388  {
389     /*
390      * Every bsr should have a volfile entry and a volblock entry
391 +    * or a VolAddr
392      *   if we are going to use positioning
393      */
394     for ( ; bsr; bsr=bsr->next) {
395 -      if (!bsr->volfile || !bsr->volblock) {
396 +      if (!((bsr->volfile && bsr->volblock) || bsr->voladdr)) {
397           return false;
398        }
399     }
400     return true;
401  }
402  
403 -
404  static BSR *store_vol(LEX *lc, BSR *bsr)
405  {
406     int token;
407 @@ -563,7 +565,41 @@
408     return bsr;
409  }
410  
411 +/*
412 + * Routine to handle Volume start/end address
413 + */
414 +static BSR *store_voladdr(LEX *lc, BSR *bsr)
415 +{
416 +   int token;
417 +   BSR_VOLADDR *voladdr;
418  
419 +   for (;;) {
420 +      token = lex_get_token(lc, T_PINT64_RANGE);
421 +      if (token == T_ERROR) {
422 +         return NULL;
423 +      }
424 +      voladdr = (BSR_VOLADDR *)malloc(sizeof(BSR_VOLADDR));
425 +      memset(voladdr, 0, sizeof(BSR_VOLADDR));
426 +      voladdr->saddr = lc->pint64_val;
427 +      voladdr->eaddr = lc->pint64_val2;
428 +      /* Add it to the end of the chain */
429 +      if (!bsr->voladdr) {
430 +         bsr->voladdr = voladdr;
431 +      } else {
432 +         /* Add to end of chain */
433 +         BSR_VOLADDR *bs = bsr->voladdr;
434 +         for ( ;bs->next; bs=bs->next)
435 +            {  }
436 +         bs->next = voladdr;
437 +      }
438 +      token = lex_get_token(lc, T_ALL);
439 +      if (token != T_COMMA) {
440 +         break;
441 +      }
442 +   }
443 +   return bsr;
444 +}
445 +
446  static BSR *store_sessid(LEX *lc, BSR *bsr)
447  {
448     int token;
449 @@ -705,6 +741,13 @@
450     }
451  }
452  
453 +void dump_voladdr(BSR_VOLADDR *voladdr)
454 +{
455 +   if (voladdr) {
456 +      Pmsg2(-1, _("VolAddr    : %lld-%lld\n"), voladdr->saddr, voladdr->eaddr);
457 +      dump_voladdr(voladdr->next);
458 +   }
459 +}
460  
461  void dump_findex(BSR_FINDEX *FileIndex)
462  {
463 @@ -795,6 +838,7 @@
464     dump_sesstime(bsr->sesstime);
465     dump_volfile(bsr->volfile);
466     dump_volblock(bsr->volblock);
467 +   dump_voladdr(bsr->voladdr);
468     dump_client(bsr->client);
469     dump_jobid(bsr->JobId);
470     dump_job(bsr->job);
471 @@ -840,6 +884,7 @@
472     free_bsr_item((BSR *)bsr->sesstime);
473     free_bsr_item((BSR *)bsr->volfile);
474     free_bsr_item((BSR *)bsr->volblock);
475 +   free_bsr_item((BSR *)bsr->voladdr);
476     free_bsr_item((BSR *)bsr->JobId);
477     free_bsr_item((BSR *)bsr->job);
478     free_bsr_item((BSR *)bsr->FileIndex);
479 Index: src/stored/record.c
480 ===================================================================
481 --- src/stored/record.c (révision 8163)
482 +++ src/stored/record.c (copie de travail)
483 @@ -422,6 +422,10 @@
484     return true;
485  }
486  
487 +uint64_t get_record_address(DEV_RECORD *rec)
488 +{
489 +   return ((uint64_t)rec->File)<<32 | rec->Block;
490 +}
491  
492  /*
493   * Read a Record from the block
494 @@ -456,7 +460,6 @@
495        rec->File = ((DEVICE *)block->dev)->EndFile;
496     }   
497  
498 -
499     /*
500      * Get the header. There is always a full header,
501      * otherwise we find it in the next block.
502 Index: src/stored/bsr.h
503 ===================================================================
504 --- src/stored/bsr.h    (révision 8163)
505 +++ src/stored/bsr.h    (copie de travail)
506 @@ -106,6 +106,12 @@
507     bool done;                         /* local done */
508  };
509  
510 +struct BSR_VOLADDR {
511 +   BSR_VOLADDR *next;
512 +   uint64_t saddr;                   /* start address */
513 +   uint64_t eaddr;                   /* end address */
514 +   bool done;                        /* local done */
515 +};
516  
517  struct BSR_FINDEX {
518     BSR_FINDEX *next;
519 @@ -157,6 +163,7 @@
520     uint32_t      found;               /* count of restored files this bsr */
521     BSR_VOLFILE  *volfile;
522     BSR_VOLBLOCK *volblock;
523 +   BSR_VOLADDR  *voladdr;
524     BSR_SESSTIME *sesstime;
525     BSR_SESSID   *sessid;
526     BSR_JOBID    *JobId;
527 Index: src/stored/protos.h
528 ===================================================================
529 --- src/stored/protos.h (révision 8163)
530 +++ src/stored/protos.h (copie de travail)
531 @@ -183,7 +183,11 @@
532  void     position_bsr_block(BSR *bsr, DEV_BLOCK *block);
533  BSR     *find_next_bsr(BSR *root_bsr, DEVICE *dev);
534  bool     is_this_bsr_done(BSR *bsr, DEV_RECORD *rec);
535 +uint64_t get_bsr_start_addr(BSR *bsr, 
536 +                            uint32_t *file=NULL,
537 +                            uint32_t *block=NULL);
538  
539 +
540  /* From mount.c */
541  bool     mount_next_read_volume(DCR *dcr);
542  
543 @@ -203,6 +207,7 @@
544  DEV_RECORD *new_record();
545  void        free_record(DEV_RECORD *rec);
546  void        empty_record(DEV_RECORD *rec);
547 +uint64_t get_record_address(DEV_RECORD *rec);
548  
549  /* From read_record.c */
550  bool read_records(DCR *dcr,