Gracefully handle filesystem inconsistencies in `RecursiveFilesystemTraversalFunction`.
PiperOrigin-RevId: 577878638
Change-Id: I696e1ace5338a026345ece2222b620cea99ae264
diff --git a/src/main/java/com/google/devtools/build/lib/skyframe/RecursiveFilesystemTraversalFunction.java b/src/main/java/com/google/devtools/build/lib/skyframe/RecursiveFilesystemTraversalFunction.java
index 70fa69d..6c03cb3 100644
--- a/src/main/java/com/google/devtools/build/lib/skyframe/RecursiveFilesystemTraversalFunction.java
+++ b/src/main/java/com/google/devtools/build/lib/skyframe/RecursiveFilesystemTraversalFunction.java
@@ -15,7 +15,6 @@
import static com.google.common.base.Preconditions.checkArgument;
import static com.google.common.base.Preconditions.checkNotNull;
-import static com.google.common.base.Preconditions.checkState;
import static java.nio.charset.StandardCharsets.UTF_8;
import com.google.common.annotations.VisibleForTesting;
@@ -36,6 +35,7 @@
import com.google.devtools.build.lib.io.FileSymlinkException;
import com.google.devtools.build.lib.io.FileSymlinkInfiniteExpansionException;
import com.google.devtools.build.lib.io.FileSymlinkInfiniteExpansionUniquenessFunction;
+import com.google.devtools.build.lib.io.InconsistentFilesystemException;
import com.google.devtools.build.lib.packages.BuildFileNotFoundException;
import com.google.devtools.build.lib.profiler.Profiler;
import com.google.devtools.build.lib.profiler.ProfilerTask;
@@ -106,6 +106,9 @@
/** A file/directory visited was part of a symlink cycle or infinite expansion. */
SYMLINK_CYCLE_OR_INFINITE_EXPANSION,
+
+ /** The filesystem told us inconsistent information. */
+ INCONSISTENT_FILESYSTEM,
}
private final RecursiveFilesystemTraversalException.Type type;
@@ -170,7 +173,11 @@
if (!rootInfo.type.exists()) {
// May be a dangling symlink or a non-existent file. Handle gracefully.
if (rootInfo.type.isSymlink()) {
- return resultForDanglingSymlink(traversal.root().asRootedPath(), rootInfo);
+ return RecursiveFilesystemTraversalValue.of(
+ ResolvedFileFactory.danglingSymlink(
+ traversal.root().asRootedPath(),
+ rootInfo.unresolvedSymlinkTarget,
+ rootInfo.metadata));
} else {
return RecursiveFilesystemTraversalValue.EMPTY;
}
@@ -248,6 +255,9 @@
// trying to get a package lookup value may have failed due to a symlink cycle.
RecursiveFilesystemTraversalException.Type exceptionType =
RecursiveFilesystemTraversalException.Type.FILE_OPERATION_FAILURE;
+ if (e instanceof InconsistentFilesystemException) {
+ exceptionType = RecursiveFilesystemTraversalException.Type.INCONSISTENT_FILESYSTEM;
+ }
if (e instanceof FileSymlinkException) {
exceptionType =
RecursiveFilesystemTraversalException.Type.SYMLINK_CYCLE_OR_INFINITE_EXPANSION;
@@ -570,27 +580,19 @@
}
/**
- * Creates result for a dangling symlink.
- *
- * @param linkName path to the symbolic link
- * @param info the {@link FileInfo} associated with the link file
- */
- private static RecursiveFilesystemTraversalValue resultForDanglingSymlink(
- RootedPath linkName, FileInfo info) {
- checkState(info.type.isSymlink() && !info.type.exists(), "{%s} {%s}", linkName, info.type);
- return RecursiveFilesystemTraversalValue.of(
- ResolvedFileFactory.danglingSymlink(linkName, info.unresolvedSymlinkTarget, info.metadata));
- }
-
- /**
* Creates results for a file or for a symlink that points to one.
*
* <p>A symlink may be direct (points to a file) or transitive (points at a direct or transitive
* symlink).
*/
- private static RecursiveFilesystemTraversalValue resultForFileRoot(
- RootedPath path, FileInfo info) {
- checkState(info.type.isFile() && info.type.exists(), "{%s} {%s}", path, info.type);
+ private static RecursiveFilesystemTraversalValue resultForFileRoot(RootedPath path, FileInfo info)
+ throws InconsistentFilesystemException {
+ if (!info.type.isFile() || !info.type.exists()) {
+ throw new InconsistentFilesystemException(
+ String.format(
+ "We were previously told %s was an existing file but it's actually %s", path, info));
+ }
+
if (info.type.isSymlink()) {
return RecursiveFilesystemTraversalValue.of(
ResolvedFileFactory.symlinkToFile(