]> git.sur5r.net Git - bacula/bacula/blobdiff - bacula/src/stored/faketape.c
ebl fix bsr code
[bacula/bacula] / bacula / src / stored / faketape.c
index 29e82de0eb6cc84e7cf06d9d6a7783e1d1d33b39..ee98d31cc7d960dda80427dc817c88dcf2e307b4 100644 (file)
@@ -101,7 +101,7 @@ void faketape_debug(int level)
 /* theses function will replace open/read/write/close/ioctl
  * in bacula core
  */
-int faketape_open(const char *pathname, int flags)
+int faketape_open(const char *pathname, int flags, ...)
 {
    ASSERT(pathname != NULL);
 
@@ -413,7 +413,7 @@ faketape::faketape()
    current_file = 0;
    current_block = -1;
 
-   max_block = 2*1024*100;      /* 100MB */
+   max_block = 2*1024*2048;      /* 2GB */
 }
 
 faketape::~faketape()
@@ -444,9 +444,7 @@ int faketape::write(const void *buffer, unsigned int count)
       return -1;
    }
 
-   if (!inplace) {
-      seek_file();
-   }
+   check_inplace();
 
    if (!atEOD) {                /* if not at the end of the data */
       truncate_file();
@@ -498,17 +496,21 @@ int faketape::weof(int count)
       return -1;
    }
    needEOF = false;
-   truncate_file();             /* nothing after this point */
 
-   /* TODO: check this */
-   current_file += count;
-   current_block = 0;
+   check_inplace();
+   truncate_file();             /* nothing after this point */
 
    uint32_t c=0;
-   seek_file();
    ::write(fd, &c, sizeof(uint32_t));
+
+   current_file += count;
+   current_block = 0;
    seek_file();
 
+   c=0;
+   ::write(fd, &c, sizeof(uint32_t));   
+   lseek(fd, lseek(fd, 0, SEEK_CUR) - sizeof(uint32_t), SEEK_SET);
+
    atEOD = false;
    atBOT = false;
    atEOF = true;
@@ -526,10 +528,12 @@ int faketape::fsf(int count)
 /*
  * 1 0 -> fsf -> 2 0 -> fsf -> 2 -1
  */
+   check_inplace();
    check_eof();
 
    int ret;
-   if (atEOT) {
+   if (atEOT || atEOD) {
+      errno = EIO;
       current_block = -1;
       return -1;
    }
@@ -543,6 +547,7 @@ int faketape::fsf(int count)
       ret = 0;
    } else {
       Dmsg0(dbglevel, "Try to FSF after EOT\n");
+      errno = EIO;
       current_file = last_file ;
       current_block = -1;
       atEOD=true;
@@ -563,6 +568,7 @@ int faketape::fsr(int count)
    uint32_t s;
    Dmsg3(dbglevel, "fsr %i:%i count=%i\n", current_file,current_block, count);
 
+   check_inplace();
    check_eof();
 
    if (atEOT) {
@@ -613,6 +619,7 @@ int faketape::bsr(int count)
    ASSERT(count == 1);
    ASSERT(fd >= 0);
 
+   check_inplace();
    check_eof();
 
    if (!count) {
@@ -628,6 +635,26 @@ int faketape::bsr(int count)
    int orig_f = current_file;
    int orig_b = current_block;
 
+   /* begin of tape, do nothing */
+   if (atBOT) {
+      errno = EIO;
+      return -1;
+   }
+
+   if (atEOF) {
+      if (!current_block) {
+        if (current_file > 0) {
+           current_file--;
+        }
+        current_block=-1;
+        errno = EIO;
+        return -1;
+
+      } else {
+        atEOF=false;
+      }
+   }
+
    current_block=0;
    seek_file();
 
@@ -664,7 +691,11 @@ int faketape::bsr(int count)
    }
 
    Dmsg2(dbglevel, "bsr %i:%i\n", current_file, current_block);
+   errno=0;
    atEOT = atEOF = atEOD = false;
+   atBOT = (current_block == 0 && current_file == 0);
+
+   current_block = -1;
 
    return 0;
 }
@@ -676,7 +707,9 @@ int faketape::bsf(int count)
    Dmsg3(dbglevel, "bsf %i:%i count=%i\n", current_file, current_block, count);
    int ret = 0;
 
+   check_inplace();
    check_eof();
+
    atBOT = atEOF = atEOT = atEOD = false;
 
    if (current_file - count < 0) {
@@ -709,7 +742,7 @@ int faketape::offline()
    atBOT = false;               /* Begin of tape */
    online = false;
 
-   file_size = 0;
+   file_block = 0;
    current_file = -1;
    current_block = -1;
    last_file = -1;
@@ -745,48 +778,63 @@ int faketape::read(void *buffer, unsigned int count)
    Dmsg2(dbglevel, "read %i:%i\n", current_file, current_block);
 
    if (atEOT || atEOD) {
-      return 0;
+      errno = EIO;
+      return -1;
    }
 
    if (atEOF) {
-      current_file++;
-      current_block=0;
-      inplace = false;
-      atEOF = false;
+      if (current_file >= last_file) {
+         atEOD = true;
+         atEOF = false;
+         current_block=-1;
+         return 0;
+      }
+      atEOF=false;
    }
 
-   if (!inplace) {
-      seek_file();
-   }
+   check_inplace();
+   check_eof();
 
    atEOD = atBOT = false;
-   current_block++;
 
+   /* reading size of data */
    nb = ::read(fd, &s, sizeof(uint32_t));
    if (nb <= 0) {
-      atEOF = true;
+      atEOF = true;            /* TODO: check this */
       return 0;
    }
+
    if (s > count) {             /* not enough buffer to read block */
       Dmsg2(dbglevel, "Need more buffer to read next block %i > %i\n",s,count);
       lseek(fd, s, SEEK_CUR);
       errno = ENOMEM;
       return -1;
    }
+
    if (!s) {                    /* EOF */
       atEOF = true;
-      lseek(fd, lseek(fd, 0, SEEK_CUR) - sizeof(uint32_t), SEEK_SET);
+      if (current_file < last_file) { /* move to next file if possible */
+         current_file++;
+         current_block = 0;
+         inplace=false;
+      }
       return 0;
    }
+
+   /* reading data itself */
    nb = ::read(fd, buffer, s);
-   if (s != nb) {
-      atEOF = true;
-      if (current_file == last_file) {
-         atEOD = true;
-         current_block = -1;
-      }
-      Dmsg0(dbglevel, "EOF during reading\n");
+   if (s != nb) {              /* read error */
+      errno=EIO;
+      atEOT = true;
+      current_block = -1;
+      Dmsg0(dbglevel, "EOT during reading\n");
+      return -1;
+   }                   /* read ok */
+
+   if (current_block >= 0) {
+      current_block++;
    }
+
    return nb;
 }
 
@@ -850,6 +898,8 @@ void faketape::update_pos()
       file_block = statp.st_blocks;
    } 
 
+   Dmsg1(dbglevel+1, "update_pos=%i\n", file_block);
+
    if (file_block > max_block) {
       atEOT = true;
    } else {
@@ -862,16 +912,17 @@ int faketape::seek_file()
    ASSERT(online);
    ASSERT(current_file >= 0);
    Dmsg2(dbglevel, "seek_file %i:%i\n", current_file, current_block);
+   inplace = true;
 
    off_t pos = ((off_t)current_file)<<FILE_OFFSET;
    if(lseek(fd, pos, SEEK_SET) == -1) {
       return -1;
    }
+
    last_file = MAX(last_file, current_file);
    if (current_block > 0) {
       fsr(current_block);
    }
-   inplace = true;
 
    return 0;
 }