Do not bother to split indirect block lists into a separate segment.
[cumulus.git] / scandir.cc
index 9a590ba..64a0dbf 100644 (file)
@@ -68,7 +68,7 @@ void metadata_flush()
 
     /* Write current metadata information to a new object. */
     LbsObject *meta = new LbsObject;
-    meta->set_group("root");
+    meta->set_group("metadata");
     meta->set_data(m.data(), m.size());
     meta->write(tss);
     meta->checksum();
@@ -145,7 +145,20 @@ int64_t dumpfile(int fd, dictionary &file_info)
         // Store a copy of the object if one does not yet exist
         if (ref.get_segment().size() == 0) {
             LbsObject *o = new LbsObject;
-            o->set_group("data");
+
+            /* We might still have seen this checksum before, if the object was
+             * stored at some time in the past, but we have decided to clean
+             * the segment the object was originally stored in (FindObject will
+             * not return such objects).  When rewriting the object contents,
+             * put it in a separate group, so that old objects get grouped
+             * together.  The hope is that these old objects will continue to
+             * be used in the future, and we obtain segments which will
+             * continue to be well-utilized. */
+            if (db->IsOldObject(block_csum, bytes))
+                o->set_group("compacted");
+            else
+                o->set_group("data");
+
             o->set_data(block_buf, bytes);
             o->write(tss);
             ref = o->get_ref();
@@ -181,7 +194,7 @@ int64_t dumpfile(int fd, dictionary &file_info)
         }
 
         LbsObject *i = new LbsObject;
-        i->set_group("indirect");
+        i->set_group("metadata");
         i->set_data(blocklist.data(), blocklist.size());
         i->write(tss);
         file_info["data"] = "@" + i->get_name();
@@ -283,8 +296,16 @@ void scanfile(const string& path)
          *   - O_NONBLOCK: prevents open() from blocking if the file was
          *     replaced by a fifo
          * We also add in O_NOATIME, since this may reduce disk writes (for
-         * inode updates). */
+         * inode updates).  However, O_NOATIME may result in EPERM, so if the
+         * initial open fails, try again without O_NOATIME.  */
         fd = open(path.c_str(), O_RDONLY|O_NOATIME|O_NOFOLLOW|O_NONBLOCK);
+        if (fd < 0) {
+            fd = open(path.c_str(), O_RDONLY|O_NOFOLLOW|O_NONBLOCK);
+        }
+        if (fd < 0) {
+            fprintf(stderr, "Unable to open file %s: %m\n", path.c_str());
+            return;
+        }
 
         /* Drop the use of the O_NONBLOCK flag; we only wanted that for file
          * open. */
@@ -458,7 +479,7 @@ int main(int argc, char *argv[])
     const string md = metadata_root.str();
 
     LbsObject *root = new LbsObject;
-    root->set_group("root");
+    root->set_group("metadata");
     root->set_data(md.data(), md.size());
     root->write(tss);
     root->checksum();