Skip to content

DrvFs without metadata returns  EPERM  from  fchmod() #41519

Description

@Zamiell

Windows Version

Microsoft Windows [Version 10.0.26100.9168]

WSL Version

2.7.11.0

Are you using WSL 1 or WSL 2?

  • WSL 2
  • WSL 1

Kernel Version

6.18.33.2-2

Distro Version

Ubuntu 26.04.1 LTS

Other Software

No response

Repro Steps

Use a WSL-native source file and a destination directory on a Windows drive mounted through DrvFs without the  metadata  option.

Confirm the mount configuration:

$ mount | grep ' on /mnt/c '
C:\ on /mnt/c type 9p (...,aname=drvfs;...,rw,...)

The mount options should not contain  metadata .

Create a writable source file with mode  0644 :

$ printf 'test\n' > /tmp/copyfile-source
$ chmod 0644 /tmp/copyfile-source
$ stat -c '%a' /tmp/copyfile-source
644

Change to any Windows directory where the current user has write access, then reproduce the failure with Node.js:

$ cd /mnt/c/path/to/a/writable/directory
$ node -e "require('node:fs').copyFileSync('/tmp/copyfile-source', './copyfile-destination')"
node:internal/fs/utils:...
Error: EPERM: operation not permitted, copyfile '/tmp/copyfile-source' -> './copyfile-destination'

The file contents are created successfully despite the reported failure:

$ cat ./copyfile-destination
test

The underlying failure can also be reproduced directly:

$ touch ./chmod-probe
$ stat -c '%a' ./chmod-probe
777
$ chmod 0644 ./chmod-probe
chmod: changing permissions of './chmod-probe': Operation not permitted

This occurs even though the Windows ACL permits the current user to modify the file. Writing the same destination with  fs.writeFileSync()  succeeds, as does copying it with GNU  cp .

Related downstream reports:

libuv/libuv#5257
nodejs/node#44261

Expected Behavior

On a DrvFs mount without metadata support, arbitrary Unix modes cannot be represented. However, an unsupported  fchmod()  request that retains at least one write bit should either succeed as a best-effort operation or otherwise avoid turning an already-successful file copy into a reported failure.

In the example above, the destination file should contain the copied data and Node.js  fs.copyFileSync()  should return successfully. This would be consistent with filesystems such as CIFS/SMB, where inability to preserve the exact Unix mode does not cause libuv’s completed copy operation to fail.

Requests that remove all write bits may still need distinct handling because DrvFs maps that state to the Windows read-only attribute.

Actual Behavior

DrvFs successfully creates and writes the destination file, but  fchmod()  returns  EPERM  when software subsequently attempts to preserve the source mode.

Node.js implements  fs.copyFileSync()  through libuv. After copying the data, libuv calls  fchmod()  on the destination. The  EPERM  result causes libuv and Node.js to report that the entire copy failed, even though the destination file was created with the correct contents.

Libuv already treats this mode-preservation failure as non-fatal on CIFS/SMB. DrvFs is exposed as a  9p  filesystem, however, so it does not receive that handling. The libuv maintainers are reluctant to parse WSL-specific procfs mount information to identify DrvFs, making it preferable for DrvFs itself to provide behavior that does not cause completed higher-level operations to report failure.

Diagnostic Logs

No response

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions