Merge tag 'upstream/3.3.1'
[debian/amanda] / device-src / xfer-source-recovery.c
index da2813473ebbdc9f3bb3efeae70c3b141f71b8ac..16673e0d1932abecda5f1ba130320e81bf797b81 100644 (file)
@@ -82,6 +82,8 @@ typedef struct XferSourceRecovery {
 
     /* timer for the duration; NULL while paused or cancelled */
     GTimer *part_timer;
+
+    gint64   size;
 } XferSourceRecovery;
 
 /*
@@ -113,7 +115,7 @@ _xsr_dbg(const char *fmt, ...)
     arglist_start(argp, fmt);
     g_vsnprintf(msg, sizeof(msg), fmt, argp);
     arglist_end(argp);
-    g_debug("XSR thd-%p: %s", g_thread_self(), msg);
+    g_debug("XSR: %s", msg);
 }
 
 /*
@@ -405,8 +407,9 @@ pull_buffer_impl(
                    _("error reading from %s: %s"),
                    self->device->device_name,
                    device_error_or_status(self->device));
+               g_mutex_unlock(self->start_part_mutex);
                wait_until_xfer_cancelled(elt->xfer);
-                goto error;
+                goto error_unlocked;
            }
 
            /* the device has signalled EOF (really end-of-part), so clean up instance
@@ -438,9 +441,30 @@ pull_buffer_impl(
 
     g_mutex_unlock(self->start_part_mutex);
 
+    if (elt->size > 0) {
+       /* initialize on first pass */
+       if (self->size == 0)
+           self->size = elt->size;
+       
+       if (self->size == -1) {
+           *size = 0;
+           amfree(buf);
+           return NULL;
+       }
+
+       if (*size > (guint64)self->size) {
+           /* return only self->size bytes */
+           *size = self->size;
+           self->size = -1;
+       } else {
+           self->size -= *size;
+       }
+    }
+
     return buf;
 error:
     g_mutex_unlock(self->start_part_mutex);
+error_unlocked:
     *size = 0;
     return NULL;
 }