Index: src/stored/faketape.c
===================================================================
---- src/stored/faketape.c (revision 7097)
-+++ src/stored/faketape.c (working copy)
+--- src/stored/faketape.c (révision 7100)
++++ src/stored/faketape.c (copie de travail)
@@ -170,6 +170,7 @@
int faketape::tape_op(struct mtop *mt_com)
{
file_block = 0;
last_file = 0;
-@@ -444,8 +465,6 @@
+@@ -436,7 +457,8 @@
+ ASSERT(buffer);
+
+ unsigned int nb;
+- Dmsg3(dbglevel, "write len=%i %i:%i\n", count, current_file,current_block);
++ Dmsg3(dbglevel+1, "write len=%i %i:%i\n",
++ count, current_file,current_block);
+
+ if (atEOT) {
+ Dmsg0(dbglevel, "write nothing, EOT !\n");
+@@ -444,8 +466,6 @@
return -1;
}
if (!atEOD) { /* if not at the end of the data */
truncate_file();
}
-@@ -460,14 +479,6 @@
+@@ -460,14 +480,6 @@
needEOF = true; /* next operation need EOF mark */
uint32_t size = count;
::write(fd, &size, sizeof(uint32_t));
nb = ::write(fd, buffer, count);
-@@ -484,43 +495,67 @@
+@@ -484,43 +496,66 @@
return nb;
}
{
ASSERT(online);
ASSERT(current_file >= 0);
- Dmsg3(dbglevel, "Writing EOF %i:%i last=%i\n",
- current_file, current_block,last_file);
-+
-+ off_t cur_FM;
+- Dmsg3(dbglevel, "Writing EOF %i:%i last=%i\n",
+- current_file, current_block,last_file);
+
if (atEOT) {
errno = ENOSPC;
+ if (!atEOD) {
+ truncate_file(); /* nothing after this point */
+ }
-+
-+ cur_FM = lseek(fd, 0, SEEK_CUR); // current position
++ last_FM = cur_FM;
++ cur_FM = lseek(fd, 0, SEEK_CUR); // current position
++
+ /* update previous next_FM */
+ lseek(fd, last_FM + sizeof(uint32_t)+sizeof(off_t), SEEK_SET);
+ ::write(fd, &cur_FM, sizeof(off_t));
+ lseek(fd, cur_FM, SEEK_SET);
+
-+ last_FM = cur_FM;
+ next_FM = 0;
+
uint32_t c=0;
- update_pos();
+ last_file = MAX(current_file, last_file);
++ Dmsg4(dbglevel, "Writing EOF %i:%i last=%lli cur=%lli next=0\n",
++ current_file, current_block, last_FM, cur_FM);
++
return 0;
}
- if ((current_file + count) <= last_file) {
- current_file += count;
- current_block = 0;
-+ if (next_FM > last_FM) { /* not the last file */
++ if (next_FM > cur_FM) { /* not the last file */
+ lseek(fd, next_FM, SEEK_SET);
+ read_next_fm(true);
+ current_file++;
Dmsg0(dbglevel, "Try to FSF after EOT\n");
errno = EIO;
current_file = last_file ;
-@@ -553,10 +597,43 @@
+@@ -553,10 +597,47 @@
atEOD=true;
ret = -1;
}
+ if (read_all) {
+ ::read(fd, &c, sizeof(c));
+ if (c != 0) {
-+ lseek(fd, lseek(fd, 0, SEEK_CUR) - sizeof(c), SEEK_SET);
++ lseek(fd, cur_FM, SEEK_SET);
+ return false;
+ }
+ }
++
++ cur_FM = lseek(fd, 0, SEEK_CUR) - sizeof(c);
++
+ ::read(fd, &last_FM, sizeof(last_FM));
+ ret = ::read(fd, &next_FM, sizeof(next_FM));
+
+ current_block=0;
+
-+ Dmsg1(dbglevel, "Read FM next=%lli\n", next_FM);
++ Dmsg3(dbglevel, "Read FM cur=%lli last=%lli next=%lli\n",
++ cur_FM, last_FM, next_FM);
+
+ return (ret == sizeof(next_FM));
+}
int faketape::fsr(int count)
{
ASSERT(online);
-@@ -568,7 +645,6 @@
+@@ -566,9 +647,9 @@
+ int i,nb, ret=0;
+ off_t where=0;
uint32_t s;
- Dmsg3(dbglevel, "fsr %i:%i count=%i\n", current_file,current_block, count);
+- Dmsg3(dbglevel, "fsr %i:%i count=%i\n", current_file,current_block, count);
++ Dmsg4(dbglevel, "fsr %i:%i EOF=%i c=%i\n",
++ current_file,current_block,atEOF,count);
- check_inplace();
check_eof();
if (atEOT) {
-@@ -595,20 +671,22 @@
+@@ -595,31 +676,29 @@
current_file, current_block, nb,s);
errno = EIO;
ret = -1;
+ */
int faketape::bsr(int count)
{
- Dmsg2(dbglevel, "bsr current_block=%i count=%i\n",
-@@ -619,7 +697,6 @@
+- Dmsg2(dbglevel, "bsr current_block=%i count=%i\n",
+- current_block, count);
+-
+ ASSERT(online);
+ ASSERT(current_file >= 0);
ASSERT(count == 1);
ASSERT(fd >= 0);
check_eof();
if (!count) {
-@@ -641,22 +718,21 @@
+@@ -635,29 +714,39 @@
+ int orig_f = current_file;
+ int orig_b = current_block;
+
++ Dmsg4(dbglevel, "bsr cur_blk=%i count=%i cur=%lli cur_FM=%lli\n",
++ current_block, count, orig, cur_FM);
++
+ /* begin of tape, do nothing */
+ if (atBOT) {
+ errno = EIO;
return -1;
}
-
- } else {
- atEOF=false;
-- }
-+ lseek(fd, last_FM, SEEK_CUR);
++ lseek(fd, cur_FM, SEEK_SET);
+ atEOF = false;
++ if (current_file > 0) {
++ current_file--;
+ }
+ current_block=-1;
+ errno = EIO;
+ return -1;
- current_block=0;
- seek_file();
+ /*
-+ * First, go to last_FM and read all blocks to find the good one
++ * First, go to cur/last_FM and read all blocks to find the good one
+ */
-+
-+ lseek(fd, last_FM, SEEK_CUR);
-+ read_fm(true);
++ if (cur_FM == orig) { /* already just before EOF */
++ lseek(fd, last_FM, SEEK_SET);
++ } else {
++ lseek(fd, cur_FM, SEEK_SET);
++ }
++
++ ret = read_fm(true);
++
do {
if (!atEOF) {
-@@ -700,31 +776,34 @@
+ last2 = last;
+@@ -674,14 +763,14 @@
+ lseek(fd, last2, SEEK_SET);
+ current_file = last_f;
+ current_block = last_b - 1;
+- Dmsg3(dbglevel, "set offset2=%lli %i:%i\n",
++ Dmsg3(dbglevel, "1 set offset2=%lli %i:%i\n",
+ last, current_file, current_block);
+
+ } else if (last > 0) {
+ lseek(fd, last, SEEK_SET);
+ current_file = last_f;
+ current_block = last_b;
+- Dmsg3(dbglevel, "set offset=%lli %i:%i\n",
++ Dmsg3(dbglevel, "2 set offset=%lli %i:%i\n",
+ last, current_file, current_block);
+ } else {
+ lseek(fd, orig, SEEK_SET);
+@@ -693,38 +782,45 @@
+ Dmsg2(dbglevel, "bsr %i:%i\n", current_file, current_block);
+ errno=0;
+ atEOT = atEOF = atEOD = false;
+- atBOT = (current_block == 0 && current_file == 0);
++ atBOT = (lseek(fd, 0, SEEK_CUR) - (sizeof(uint32_t)+2*sizeof(off_t))) == 0;
+
+- current_block = -1;
++ if (orig_b == -1) {
++ current_block = orig_b;
++ }
+
return 0;
}
- seek_file();
+ Dmsg1(dbglevel, "bfs last=%lli\n", last_FM);
+ lseek(fd, last_FM, SEEK_SET);
++ read_fm(true); /* update last/cur/next_FM */
++ lseek(fd, cur_FM, SEEK_SET);
current_file--;
- /* go just before last EOF */
- lseek(fd, lseek(fd, 0, SEEK_CUR) - sizeof(uint32_t), SEEK_SET);
}
return ret;
}
-@@ -749,6 +828,9 @@
+@@ -749,6 +845,9 @@
return 0;
}
int faketape::close()
{
check_eof();
-@@ -756,18 +838,15 @@
+@@ -756,18 +855,15 @@
fd = -1;
return 0;
}
int faketape::read(void *buffer, unsigned int count)
{
ASSERT(online);
-@@ -778,6 +857,10 @@
- Dmsg2(dbglevel, "read %i:%i\n", current_file, current_block);
+@@ -775,7 +871,7 @@
+ unsigned int nb;
+ uint32_t s;
+
+- Dmsg2(dbglevel, "read %i:%i\n", current_file, current_block);
++ Dmsg2(dbglevel+1, "read %i:%i\n", current_file, current_block);
if (atEOT || atEOD) {
-+ if (eot_count < 2) { // first two reads return 0, after EIO
-+ eot_count++;
-+ return 0;
-+ }
errno = EIO;
- return -1;
+@@ -783,7 +879,7 @@
}
-@@ -792,10 +875,10 @@
+
+ if (atEOF) {
+- if (current_file >= last_file) {
++ if (!next_FM) {
+ atEOD = true;
+ atEOF = false;
+ current_block=-1;
+@@ -792,7 +888,6 @@
atEOF=false;
}
check_eof();
atEOD = atBOT = false;
-+ eot_count = 0;
-
- /* reading size of data */
- nb = ::read(fd, &s, sizeof(uint32_t));
-@@ -813,11 +896,10 @@
+@@ -813,11 +908,10 @@
if (!s) { /* EOF */
atEOF = true;
return 0;
}
-@@ -825,7 +907,7 @@
+@@ -825,7 +919,7 @@
nb = ::read(fd, buffer, s);
if (s != nb) { /* read error */
errno=EIO;
current_block = -1;
Dmsg0(dbglevel, "EOT during reading\n");
return -1;
-@@ -860,36 +942,25 @@
+@@ -860,36 +954,24 @@
return -1;
}
file_block = 0;
current_block = 0;
current_file = 0;
-+ next_FM = last_FM = 0;
-+ eot_count = 0;
++ cur_FM = next_FM = last_FM = 0;
needEOF = false;
- inplace = true;
atBOT = true;
void faketape::update_pos()
{
ASSERT(online);
-@@ -901,32 +972,12 @@
+@@ -901,32 +983,12 @@
Dmsg1(dbglevel+1, "update_pos=%i\n", file_block);
if (file_block > max_block) {
Dmsg0(dbglevel+1, "===================\n");
Index: src/stored/faketape.h
===================================================================
---- src/stored/faketape.h (revision 7097)
-+++ src/stored/faketape.h (working copy)
-@@ -56,35 +56,38 @@
+--- src/stored/faketape.h (révision 7100)
++++ src/stored/faketape.h (copie de travail)
+@@ -56,35 +56,39 @@
private:
int fd; /* Our file descriptor */
+ off_t file_block; /* size */
off_t max_block;
-+ off_t last_FM; /* last file mark (current file) */
++ off_t last_FM; /* last file mark (last file) */
+ off_t next_FM; /* next file mark (next file) */
++ off_t cur_FM; /* current file mark */
+
bool atEOF; /* End of file */
bool atEOT; /* End of media */