-
Notifications
You must be signed in to change notification settings - Fork 5.5k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
8264400: (fs) WindowsFileStore equality depends on how the FileStore was constructed #3279
Conversation
👋 Welcome back bpb! A progress list of the required criteria for merging this PR into |
Webrevs
|
volInfo.fileSystemName().equals(otherInfo.fileSystemName()) && | ||
volInfo.volumeSerialNumber() == otherInfo.volumeSerialNumber(); | ||
} | ||
return false; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The volType == DRIVE_REMOTE case is the reason why we didn't fix this one in the past. Can you summarise that the VolumeInfomation is for this case?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I was not able to test that case yet. Using the VolumeInformation was intended to limit spurious equality.
Can you explain abut DRIVE_REMOTE?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I was not able to test that case yet. Using the VolumeInformation was intended to limit spurious equality.
Can you explain abut DRIVE_REMOTE?
I think the volume type will be DRIVE_REMOTE when the root is a UNC (the constants for the volume types are defined in WIndowsConstants). I'm not 100% sure if the server and share names should be compared with or without regard to case so I think we have a bit more exploration to do there. The DRIVE_FIXED case is clear, and it would be good to at least get that fixed as there has been C:\ vs. c:\ confusion in a number of bug reports.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Based on testing in a Win 10 VM, the volume type is in fact DRIVE_REMOTE. The volume serial number however is zero. From what I can test via testing and reading the server and share names don't care about case.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If we are unsure, for UNC, perhaps the server and share name comparisons can remain case sensitive but the file path component comparison be case insensitive?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe this is something that the Microsoft folks can help us with, it might be that it depends on the transport.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good idea. I will ask them.
Mailing list message from Bernd Eckenfels on nio-dev: Hello, Is it instead possible to store a normalized version of the store base path (for the purpose of equals but also for display)? This would reduce dependence of file name casing semantics which does not in all cases depend only on the host operating system. Maybe using lpRootPathName if present in GetVolumeInformation? Gruss On Thu, 1 Apr 2021 18:03:30 GMT, Alan Bateman <alanb at openjdk.org> wrote:
Good idea. I will ask them. ------------- PR: https://git.openjdk.java.net/jdk/pull/3279 |
Mailing list message from Brian Burkhalter on nio-dev: Hello, On Apr 1, 2021, at 1:29 PM, Bernd Eckenfels <ecki at zusammenkunft.net<mailto:ecki at zusammenkunft.net>> wrote: Is it instead possible to store a normalized version of the store base path (for the purpose of equals but also for display)? This would reduce dependence of file name casing semantics which does not in all cases depend only on the host operating system. It?s not clear what is intended here. WindowsFileStore does not have a base path itself. Its root path is the path supplied as a parameter of Files.getFileStore(). Maybe using lpRootPathName if present in GetVolumeInformation? lpRootPathName is the same as WindowsFileStore.root and is an input to GetVolumeInformationW() [1]. Thanks, Brian [1] https://docs.microsoft.com/en-us/windows/win32/api/fileapi/nf-fileapi-getvolumeinformationw |
Mailing list message from Alan Bateman on nio-dev: On 01/04/2021 22:46, Brian Burkhalter wrote:
I think it would be useful to looking at the values of the volInfo field -Alan. |
I already have this information.
|
Mailing list message from Alan Bateman on nio-dev: On 02/04/2021 17:53, Brian Burkhalter wrote:
It would be useful for the discussion if you could repeat with UNC One other thing is that if we do change the equals (and I think we need -Alan |
I already tested with other cases but didn't include it:
Good point about |
If we want to constrain the case insensitive comparison to fixed drives, then this might work:
|
Yes, although it would be good to extend this to the DRIVE_REMOTE and other cases too, but that requires being confident that it is correct (and I'm not sure we have enough information to say this yet). An initial change for the DRIVE_FIXED case is okay. It will mean using Locale.ROOT or Locale.US. Also the hash code will need to be cached. |
(Commit message for 9260dfd intended |
1 similar comment
(Commit message for 9260dfd intended |
@@ -44,6 +52,9 @@ | |||
private final int volType; | |||
private final String displayName; // returned by toString | |||
|
|||
private boolean hasHashCode = false; // as hashCode can be any int |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is buggy. It would be simpler to drop hasHashCode and just race when hash is 0.
@@ -221,8 +231,7 @@ public boolean supportsFileAttributeView(String name) { | |||
if (name.equals("owner")) | |||
return supportsFileAttributeView(FileOwnerAttributeView.class); | |||
if (name.equals("user")) | |||
return supportsFileAttributeView(UserDefinedFileAttributeView.class); | |||
return false; | |||
return supportsFileAttributeView(UserDefinedFileAttributeView.class); return false; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can you revert this change, it's not part of the fix and it makes this method harder to maintain.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I did revert it before but I guess it crept back in ... sigh.
@@ -232,12 +241,20 @@ public boolean equals(Object ob) { | |||
if (!(ob instanceof WindowsFileStore)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We can change this to
if (ob instanced WindowsFileStore other) { ... } and it will avoid the cast.
} | ||
|
||
@Override | ||
public int hashCode() { | ||
return root.hashCode(); | ||
if (hashCode == 0) { // Don't care about race | ||
hashCode = volType == DRIVE_FIXED ? |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
minor nit but would be a bit easier to read if changed to
hashCode = (volType == DRIVE_FIXED) ? ...
*/ | ||
FileSystem fs = FileSystems.getDefault(); | ||
FileStore upper = Files.getFileStore(fs.getPath("C:\\")); | ||
FileStore lower = Files.getFileStore(fs.getPath("c:\\")); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Path.of("c:\") can be used if you want.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Will simplify to that in final commit.
@@ -44,6 +52,8 @@ | |||
private final int volType; | |||
private final String displayName; // returned by toString | |||
|
|||
private int hashCode = 0; | |||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good, I think this is safe and equals/hashCode are consistent. I suspect we can extend this to other (maybe all) volume type but it needs a bit more exploration. Minor nit is that you can't need to initialise hashCode to 0.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this issue was specific to the DRIVE_FIXED
case so further enhancement can be done under another issue once the information becomes knowd.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this issue was specific to the
DRIVE_FIXED
case so further enhancement can be done under another issue once the information becomes knowd.
That's okay with me.
/** | ||
* Test: FileStore.equals() should not be case sensitive | ||
*/ | ||
FileSystem fs = FileSystems.getDefault(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I assume this line is no longer needed.
@bplb This change now passes all automated pre-integration checks. ℹ️ This project also has non-automated pre-integration requirements. Please see the file CONTRIBUTING.md for details. After integration, the commit message for the final commit will be:
You can use pull request commands such as /summary, /contributor and /issue to adjust it as needed. At the time when this comment was updated there had been 314 new commits pushed to the
As there are no conflicts, your changes will automatically be rebased on top of these commits when integrating. If you prefer to avoid this automatic rebasing, please check the documentation for the /integrate command for further details. ➡️ To integrate this PR with the above commit message to the |
/integrate |
@bplb Since your change was applied there have been 315 commits pushed to the
Your commit was automatically rebased without conflicts. Pushed as commit cc54de7. 💡 You may see a message that your pull request was closed with unmerged commits. This can be safely ignored. |
hashCode = (volType == DRIVE_FIXED) ? | ||
root.toLowerCase(Locale.ROOT).hashCode() : root.hashCode(); | ||
} | ||
return hashCode; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
As I know, to make data race benign, field should be read only once. But there is second read which can still return 0
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You can are right, missed in the final review (as this one went through many iterations).
Mailing list message from Brian Burkhalter on nio-dev: On Apr 9, 2021, at 11:46 PM, Alan Bateman <alanb at openjdk.java.net<mailto:alanb at openjdk.java.net>> wrote: On Fri, 9 Apr 2021 22:24:03 GMT, Andrey Turbanov <github.com+741251+turbanoff at openjdk.org<mailto:github.com+741251+turbanoff at openjdk.org>> wrote: Brian Burkhalter has updated the pull request incrementally with one additional commit since the last revision: 8264400: Remove vestigial FileSystems.getDefault() src/java.base/windows/classes/sun/nio/fs/WindowsFileStore.java line 257: 255: root.toLowerCase(Locale.ROOT).hashCode() : root.hashCode(); As I know, to make data race benign, field should be read only once. But there is second read which can still return `0` You can are right, missed in the final review (as this one went through many iter Filed JDK-8265100 to address this oversight. |
Please consider this change to make
sun.nio.fs.WindowsFileStore.equals()
returntrue
if the root strings of the two objects are equal under case insensitive comparison, and the twoWindowsFileStore
s have the same volume information.Progress
Issue
Reviewers
Reviewing
Using
git
Checkout this PR locally:
$ git fetch https://git.openjdk.java.net/jdk pull/3279/head:pull/3279
$ git checkout pull/3279
Update a local copy of the PR:
$ git checkout pull/3279
$ git pull https://git.openjdk.java.net/jdk pull/3279/head
Using Skara CLI tools
Checkout this PR locally:
$ git pr checkout 3279
View PR using the GUI difftool:
$ git pr show -t 3279
Using diff file
Download this PR as a diff file:
https://git.openjdk.java.net/jdk/pull/3279.diff