Skip to content
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

file:read_file_info fails on Windows with {error,badarg} for files on SMB share if last access time is not set #6356

Closed
chi-lambda opened this issue Oct 10, 2022 · 3 comments
Assignees
Labels
bug Issue is reported as a bug team:VM Assigned to OTP team VM

Comments

@chi-lambda
Copy link

Describe the bug
file:read_file_info fails on Windows (native) when called with a file on an SMB share, no matter if UNC path or mapped drive, if no last access time is set.

To Reproduce
Create a file from the client on an SMB share. Confirm in explorer that last access time is not set (displays as 00:00:00). This may require a Linux samba server instead of an actual Windows server. Then call file:read_file_info on that file on the client. It should fail with {error,badarg}.

Expected behavior
file:read_file_info returns the file information, similar to this (WSL1 output):

{ok,{file_info,583,regular,read_write,
               {{30828,9,14},{4,48,5}},
               {{2022,10,10},{8,27,53}},
               {{2022,10,10},{8,27,53}},
               33279,1,21,0,6831742,0,0}}

Affected versions
Found in OTP 25.1.

Additional context
Erlang in WSL1 shows garbage for last access time (with a year in the 30000s), but doesn't fail.

Calling touch on the file on the server "fixes" the issue, as it sets the last access time.

@chi-lambda chi-lambda added the bug Issue is reported as a bug label Oct 10, 2022
@chi-lambda
Copy link
Author

I think I have figured out what's happening:

  • If last access time is not set, its value is 2^63-1.
  • That, divided by TICKS_PER_SECOND==10000000, is 922337203685, subtract EPOCH_DIFFERENCE==11644473600 and you get 910692730085.
  • In prim_file.erl:634, we call adjust_time with TimeType==local, which calls erlang:universaltime_to_localtime(erlang:posixtime_to_universaltime(910692730085))
  • erlang:posixtime_to_universaltime(910692730085)=={{30828,9,14},{2,48,5}}, but on native Windows, erlang:universaltime_to_localtime({{30828,9,14},{2,48,5}}) fails with
** exception error: bad argument
     in function  erlang:posixtime_to_universaltime/1
        called as erlang:posixtime_to_universaltime({{30828,9,14},{2,48,5}})
        *** argument 1: not an integer
  • The cause (I think) for that is that {{30828,9,14},{2,48,5}} is not a valid SYSTEMTIME, which ends in 30827, so sys_localtime_r fails. (On Linux and other Unix-like OSs, we just call localtime_r, which doesn't have that problem.)

I haven't localized the exact place where it fails, because in the end, this is just a case of "garbage in, garbage out". If there is no valid data in the last-access-time field, we should return nothing there or any arbitrary, unproblematic value (say {{9999,12,31},{23,59,59}}).

Side note: Who reads the last access time anyway – especially on Windows, where it's usually disabled?

@IngelaAndin IngelaAndin added the team:VM Assigned to OTP team VM label Oct 17, 2022
@jhogberg
Copy link
Contributor

jhogberg commented Dec 5, 2022

Thanks for your report, and sorry for the late reply. I got back from long-term leave late last week and didn't manage to fix this in time for the upcoming OTP 25.2 patch. I'll make a PR with the fix as soon as that is released.

jhogberg added a commit that referenced this issue Dec 22, 2022
…nto maint

* john/erts/read_file_info-smb-share/OTP-18348/GH-6356:
  erts: Cap file times to {{9999,12,31},{23,59,59}}
  erts: Silently convert FILETIME of -1 to 0 on Windows
@jhogberg
Copy link
Contributor

I've merged a fix into maint now, which will be released as 25.3 early next year. Thanks again for your report!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Issue is reported as a bug team:VM Assigned to OTP team VM
Projects
None yet
Development

No branches or pull requests

3 participants