diff --git a/src/main/java/com/google/devtools/build/lib/windows/WindowsFileOperations.java b/src/main/java/com/google/devtools/build/lib/windows/WindowsFileOperations.java index 89c7e1484f3a4e..d5e2058e57e015 100644 --- a/src/main/java/com/google/devtools/build/lib/windows/WindowsFileOperations.java +++ b/src/main/java/com/google/devtools/build/lib/windows/WindowsFileOperations.java @@ -70,6 +70,7 @@ private WindowsFileOperations() { private static final int CREATE_JUNCTION_ALREADY_EXISTS_BUT_NOT_A_JUNCTION = 4; private static final int CREATE_JUNCTION_ACCESS_DENIED = 5; private static final int CREATE_JUNCTION_DISAPPEARED = 6; + private static final int CREATE_JUNCTION_NOT_SUPPORTED = 7; // Keep CREATE_SYMLINK_* values in sync with src/main/native/windows/file.h. private static final int CREATE_SYMLINK_SUCCESS = 0; @@ -172,6 +173,9 @@ public static void createJunction(String name, String target) throws IOException case CREATE_JUNCTION_DISAPPEARED: error[0] = "the junction's path got modified unexpectedly"; break; + case CREATE_JUNCTION_NOT_SUPPORTED: + error[0] = "filesystem does not support junctions"; + break; default: // This is CREATE_JUNCTION_ERROR (1). The JNI code puts a custom message in 'error[0]'. break; diff --git a/src/main/native/windows/file.cc b/src/main/native/windows/file.cc index ed6653e3e60d75..7a24589285e28a 100644 --- a/src/main/native/windows/file.cc +++ b/src/main/native/windows/file.cc @@ -456,6 +456,11 @@ int CreateJunction(const wstring& junction_name, const wstring& junction_target, if (err == ERROR_DIR_NOT_EMPTY) { return CreateJunctionResult::kAlreadyExistsButNotJunction; } + // ERROR_INVALID_FUNCTION indicates the filesystem doesn't support + // junction/reparse point operations (e.g., virtiofs). + if (err == ERROR_INVALID_FUNCTION) { + return CreateJunctionResult::kNotSupported; + } // Some unknown error occurred. if (error) { *error = MakeErrorMessage(WSTR(__FILE__), __LINE__, L"DeviceIoControl", @@ -587,6 +592,11 @@ int ReadSymlinkOrJunction(const wstring& path, wstring* result, if (err == ERROR_NOT_A_REPARSE_POINT) { return ReadSymlinkOrJunctionResult::kNotALink; } + // ERROR_INVALID_FUNCTION indicates the filesystem doesn't support + // reparse point operations (e.g., virtiofs). Treat as not a link. + if (err == ERROR_INVALID_FUNCTION) { + return ReadSymlinkOrJunctionResult::kNotALink; + } // Some unknown error occurred. if (error) { diff --git a/src/main/native/windows/file.h b/src/main/native/windows/file.h index 4e7c6557b655e5..973899fdb55b37 100644 --- a/src/main/native/windows/file.h +++ b/src/main/native/windows/file.h @@ -113,6 +113,7 @@ struct CreateJunctionResult { kAlreadyExistsButNotJunction = 4, kAccessDenied = 5, kDisappeared = 6, + kNotSupported = 7, }; };