]> git.sur5r.net Git - bacula/bacula/commitdiff
ebl Fix bug when fsr after reading EOF
authorEric Bollengier <eric@eb.homelinux.org>
Sun, 1 Jun 2008 13:00:10 +0000 (13:00 +0000)
committerEric Bollengier <eric@eb.homelinux.org>
Sun, 1 Jun 2008 13:00:10 +0000 (13:00 +0000)
git-svn-id: https://bacula.svn.sourceforge.net/svnroot/bacula/trunk@7084 91ce42f0-d328-0410-95d8-f526ca767f89

bacula/src/stored/faketape.c
bacula/src/stored/faketape.h

index b3025571f4a9ac7e39042dcbdecd024b2efb0b8d..3de61b4ffdd285938247c2a69f98bb916298acd9 100644 (file)
@@ -444,9 +444,8 @@ int faketape::write(const void *buffer, unsigned int count)
       return -1;
    }
 
-   if (!inplace) {
-      seek_file();
-   }
+   Dmsg1(dbglevel, "write inplace=%i\n", inplace);
+   check_inplace();
 
    if (!atEOD) {                /* if not at the end of the data */
       truncate_file();
@@ -498,17 +497,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 +529,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 +548,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 +569,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 +620,7 @@ int faketape::bsr(int count)
    ASSERT(count == 1);
    ASSERT(fd >= 0);
 
+   check_inplace();
    check_eof();
 
    if (!count) {
@@ -676,7 +684,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) {
@@ -745,48 +755,61 @@ 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 */
+
+   current_block++;
+
    return nb;
 }
 
@@ -864,16 +887,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;
 }
index 5101eb0a8c2d5c85c3ed3e15d4d76a6246796a6d..60af5020df1aaf306b4aad05c3613e216ef53145 100644 (file)
@@ -45,7 +45,7 @@
 /* 
  * Theses functions will replace open/read/write
  */
-int faketape_open(const char *pathname, int flags);
+int faketape_open(const char *pathname, int flags, ...);
 int faketape_read(int fd, void *buffer, unsigned int count);
 int faketape_write(int fd, const void *buffer, unsigned int count);
 int faketape_close(int fd);
@@ -77,6 +77,7 @@ private:
    int truncate_file();
    int seek_file();
    void check_eof() { if(needEOF) weof(1);};
+   void check_inplace() { if (!inplace) seek_file();};
    void update_pos();
 
 public: