Author: frm
Date: Fri Apr  7 07:41:21 2017
New Revision: 1790514

URL: http://svn.apache.org/viewvc?rev=1790514&view=rev
Log:
OAK-6046 - Make initial references for cleanup consistent with cleaned up TARs

Modified:
    
jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/file/FileStore.java
    
jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/file/TarFiles.java

Modified: 
jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/file/FileStore.java
URL: 
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/file/FileStore.java?rev=1790514&r1=1790513&r2=1790514&view=diff
==============================================================================
--- 
jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/file/FileStore.java
 (original)
+++ 
jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/file/FileStore.java
 Fri Apr  7 07:41:21 2017
@@ -155,6 +155,21 @@ public class FileStore extends AbstractF
     @Nonnull
     private final SegmentNotFoundExceptionListener snfeListener;
 
+    private final Supplier<Set<UUID>> referencesSupplier = new 
Supplier<Set<UUID>>() {
+
+        @Override
+        public Set<UUID> get() {
+            Set<UUID> references = newHashSet();
+            for (SegmentId id : tracker.getReferencedSegmentIds()) {
+                if (id.isBulkSegmentId()) {
+                    references.add(id.asUUID());
+                }
+            }
+            return references;
+        }
+
+    };
+
     FileStore(final FileStoreBuilder builder) throws 
InvalidFileStoreVersionException, IOException {
         super(builder);
 
@@ -810,13 +825,7 @@ public class FileStore extends AbstractF
             // to clear stale weak references in the SegmentTracker
             System.gc();
 
-            Set<UUID> bulkRefs = newHashSet();
-            for (SegmentId id : tracker.getReferencedSegmentIds()) {
-                if (id.isBulkSegmentId()) {
-                    bulkRefs.add(id.asUUID());
-                }
-            }
-            CleanupResult cleanupResult = tarFiles.cleanup(bulkRefs, 
compactionResult.reclaimer());
+            CleanupResult cleanupResult = tarFiles.cleanup(referencesSupplier, 
compactionResult.reclaimer());
             if (cleanupResult.isInterrupted()) {
                 gcListener.info("TarMK GC #{}: cleanup interrupted", GC_COUNT);
             }

Modified: 
jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/file/TarFiles.java
URL: 
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/file/TarFiles.java?rev=1790514&r1=1790513&r2=1790514&view=diff
==============================================================================
--- 
jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/file/TarFiles.java
 (original)
+++ 
jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/file/TarFiles.java
 Fri Apr  7 07:41:21 2017
@@ -45,6 +45,7 @@ import java.util.regex.Matcher;
 import java.util.regex.Pattern;
 
 import com.google.common.base.Predicate;
+import com.google.common.base.Supplier;
 import com.google.common.io.Closer;
 import org.apache.jackrabbit.oak.plugins.blob.ReferenceCollector;
 import org.apache.jackrabbit.oak.segment.SegmentGraph.SegmentGraphVisitor;
@@ -404,7 +405,7 @@ class TarFiles implements Closeable {
         writer = newWriter;
     }
 
-    CleanupResult cleanup(Set<UUID> references, Predicate<Integer> 
reclaimGeneration) throws IOException {
+    CleanupResult cleanup(Supplier<Set<UUID>> referencesSupplier, 
Predicate<Integer> reclaimGeneration) throws IOException {
         checkReadWrite();
 
         CleanupResult result = new CleanupResult();
@@ -437,6 +438,13 @@ class TarFiles implements Closeable {
                 cleaned.put(reader, reader);
                 result.reclaimedSize += reader.size();
             }
+
+            // The set of references has to be computed while holding the lock.
+            // This prevents a time-of-check to time-of-use race condition. See
+            // OAK-6046 for further details.
+
+            Set<UUID> references = referencesSupplier.get();
+
             Set<UUID> reclaim = newHashSet();
             for (TarReader reader : cleaned.keySet()) {
                 if (shutdown) {


Reply via email to