My Python project works correctly on Windows but it encounters bugs on WSL2. I have done some debugging and finally localized the error to a compatibility problem. That is, in WSL2, Python's native functions os.rename() and os.replace() cannot deal with files on a mounted ReFS drive well, and PermissionError occurs.
For example, we have a ReFS drive F and a file F:\text.txt on Windows. Then, F: will be mounted to WSL2 as /mnt/f and the file path is /mnt/f/text.txt. The test with PermissionError is:
import os
with open('/mnt/f/text.txt','w'):
pass
assert os.path.exists('/mnt/f/text.txt')
try:
os.rename('/mnt/f/text.txt','/mnt/f/text2.txt')
except PermissionError as e:
print(e)
# [Errno 1] Operation not permitted: '/mnt/f/text.txt' -> '/mnt/f/text2.txt'
try:
os.replace('/mnt/f/text.txt','/mnt/f/text2.txt')
except PermissionError as e:
print(e)
# [Errno 1] Operation not permitted: '/mnt/f/text.txt' -> '/mnt/f/text2.txt'
os.remove('/mnt/f/text.txt') # passed
assert not os.path.exists('/mnt/f/text.txt')
But, if we turn to a normal NTFS drive, such as X:, and the test with no bug is:
import os
with open('/mnt/x/text.txt','w'):
pass
assert os.path.exists('/mnt/x/text.txt')
try:
os.rename('/mnt/x/text.txt','/mnt/x/text2.txt')
except PermissionError as e:
print(e)
with open('/mnt/x/text.txt','w'):
pass
assert os.path.exists('/mnt/x/text.txt')
try:
os.replace('/mnt/x/text.txt','/mnt/x/text3.txt')
except PermissionError as e:
print(e)
assert not os.path.exists('/mnt/x/text.txt')
os.remove('/mnt/x/text2.txt')
assert not os.path.exists('/mnt/x/text2.txt')
os.remove('/mnt/x/text3.txt')
assert not os.path.exists('/mnt/x/text3.txt')
So, the conclusions from the above tests are:
- WSL2 and its Python do not completely support ReFS
- In the Python run on WSL2,
os.rename()andos.replace()do not support files in a ReFS drive that mounted to WSL2 os.remove()is supported.- When it comes to NTFS drive, all the above operations are supported.
To solve the problem, I have tried the following 2 methods but they both do not work respectively:
- modify
/etc/wsl.confby adding:
and then restart WSL2.[automount] options = "metadata,umask=22,fmask=11" - re-mount target drive by arg
nopermsudo umount /mnt/f sudo mount -t drvfs F: /mnt/f -o noperm
So, how to fix it? How can I rename files in a Windows ReFS dive that is mounted to WSL2?
Thanks in advance.