TBR: derat@chromium.org
diff --git a/install_action.cc b/install_action.cc
index 9c644df..c70867e 100644
--- a/install_action.cc
+++ b/install_action.cc
@@ -63,11 +63,14 @@
   ScopedFilesystemUnmounter filesystem_unmounter(mountpoint);
 
   {
-    // iterate through existing fs, deleting unneeded files
+    // Iterate through existing fs, deleting unneeded files
+    // Delete files that don't exist in the update, or exist but are
+    // hard links.
     FilesystemIterator iter(mountpoint,
                             utils::SetWithValue<string>("/lost+found"));
     for (; !iter.IsEnd(); iter.Increment()) {
-      if (!parser.ContainsPath(iter.GetPartialPath())) {
+      if (!parser.ContainsPath(iter.GetPartialPath()) ||
+          parser.GetFileAtPath(iter.GetPartialPath()).has_hardlink_path()) {
         VLOG(1) << "install removing local path: " << iter.GetFullPath();
         TEST_AND_RETURN(utils::RecursiveUnlinkDir(iter.GetFullPath()));
       }
@@ -96,7 +99,12 @@
   TEST_AND_RETURN_FALSE_ERRNO((result == 0) || (errno == ENOENT));
   bool exists = (result == 0);
   // Create the proper file
-  if (S_ISDIR(file.mode())) {
+  if (file.has_hardlink_path()) {
+    TEST_AND_RETURN_FALSE(file.has_hardlink_path());
+    TEST_AND_RETURN_FALSE_ERRNO(link(
+        (mountpoint + file.hardlink_path()).c_str(),
+        (mountpoint + path).c_str()) == 0);
+  } else if (S_ISDIR(file.mode())) {
     if (!exists) {
       TEST_AND_RETURN_FALSE_ERRNO(
           (mkdir((mountpoint + path).c_str(), file.mode())) == 0);
@@ -186,6 +194,7 @@
   dev_t dev = 0;
   if (S_ISCHR(file.mode()) || S_ISBLK(file.mode())) {
     vector<char> dev_proto;
+    TEST_AND_RETURN_FALSE(file.has_data_format());
     TEST_AND_RETURN_FALSE(parser.ReadDataVector(file.data_offset(),
                                                 file.data_length(),
                                                 &dev_proto));