Fix a bug in computing the size of a segment that led to utilization > 1.0.
[cumulus.git] / metadata.cc
index dac3d20..c27278b 100644 (file)
@@ -106,7 +106,6 @@ MetadataWriter::MetadataWriter(TarSegmentStore *store,
         throw IOException("Error opening statcache");
     }
 
-    found_match = false;
     old_metadata_eof = false;
 
     this->store = store;
@@ -187,28 +186,25 @@ bool MetadataWriter::find(const string& path)
     while (!old_metadata_eof) {
         string old_path = uri_decode(old_metadata["name"]);
         int cmp = pathcmp(old_path.c_str(), path_str);
-        if (cmp == 0) {
-            found_match = true;
+        if (cmp == 0)
             return true;
-        } else if (cmp > 0) {
-            found_match = false;
+        else if (cmp > 0)
             return false;
-        } else {
+        else
             read_statcache();
-        }
     }
 
-    found_match = false;
     return false;
 }
 
 /* Does a file appear to be unchanged from the previous time it was backed up,
- * based on stat information?
- *
- * TODO: Notice files that were modified as they were being backed up the last
- * time. */
+ * based on stat information? */
 bool MetadataWriter::is_unchanged(const struct stat *stat_buf)
 {
+    if (old_metadata.find("volatile") != old_metadata.end()
+        && parse_int(old_metadata["volatile"]) != 0)
+        return false;
+
     if (old_metadata.find("ctime") == old_metadata.end())
         return false;
     if (stat_buf->st_ctime != parse_int(old_metadata["ctime"]))
@@ -256,11 +252,9 @@ list<ObjectReference> MetadataWriter::get_blocks()
             s++;
         }
 
-        ObjectReference *r = ObjectReference::parse(ref);
-        if (r != NULL) {
-            blocks.push_back(*r);
-            delete r;
-        }
+        ObjectReference r = ObjectReference::parse(ref);
+        if (!r.is_null())
+            blocks.push_back(r);
     }
 
     return blocks;
@@ -275,6 +269,11 @@ void MetadataWriter::metadata_flush()
     ObjectReference indirect;
     for (list<MetadataItem>::iterator i = items.begin();
          i != items.end(); ++i) {
+        // If indirectly referencing any other metadata logs, be sure those
+        // segments are properly referenced.
+        if (i->reused)
+            add_segment(i->ref.get_segment());
+
         // Write out an indirect reference to any previous objects which could
         // be reused
         if (!i->reused || !indirect.merge(i->ref)) {
@@ -350,11 +349,10 @@ void MetadataWriter::add(dictionary info)
     item.text += encode_dict(info) + "\n";
 
     if (info == old_metadata) {
-        ObjectReference *ref = ObjectReference::parse(old_metadata_loc);
-        if (ref != NULL) {
+        ObjectReference ref = ObjectReference::parse(old_metadata_loc);
+        if (!ref.is_null()) {
             item.reused = true;
-            item.ref = *ref;
-            delete ref;
+            item.ref = ref;
         }
     }