Logic Encoder Blog

WSL File Transfer: Reliable Windows–Linux Copies and Metadata Checks

Aug 17, 2025 Logic Encoder 9 min read

WSL file transfer: choose the filesystem before choosing the command

For occasional copies, open your Linux distribution through \\wsl.localhost\Ubuntu in Windows File Explorer. For repeatable directory transfers, use rsync with a dry run and explicit paths. For a Linux tree whose permissions and links matter, use an archive. Keep a project in the filesystem used by its main tools: Linux work generally belongs in the WSL filesystem, Windows work in the Windows filesystem.

In this guide

This guide separates three issues that are often confused: copying bytes, preserving filesystem metadata, and fixing text encoding or line endings. A copy can succeed while a script still contains CRLF line endings. A fast bulk copy can coexist with slow operations on thousands of small files. There is no universal MB/s result for every WSL installation.

Windows and Linux filesystem access with an export and restore-verification workflow.
Generated conceptual illustration. Example paths and the restoration workflow are explained in the guide.

Identify the two sides of the transfer

Inside WSL, a path such as /home/yourname/project refers to the Linux filesystem. /mnt/c/Users/YourName/Documents usually refers to a mounted Windows drive. From Windows, the supported distribution share exposes the Linux files; it is different from directly manipulating the distribution’s virtual disk.

# Run these in the WSL terminal.
pwd
df -T .
wslpath -u 'C:\Users\YourName\Documents'
wslpath -w "$HOME/project"

Replace example usernames and paths with your actual locations. The distribution name in the Windows share must match your installation. In PowerShell, use wsl --list --verbose to find it. Both \\\\wsl.localhost\\Ubuntu and the established \\\\wsl$\\Ubuntu share form can be useful; the distribution name is not necessarily Ubuntu.

Microsoft’s filesystem guidance explains why storing files alongside the tools that use them helps performance. A Linux-heavy project on /mnt/c can incur different metadata and cross-filesystem costs from a project under the Linux home directory. Those costs depend on workload and environment; they are not a fixed slowdown factor.

Windows and Linux path examples show supported access to each filesystem.
Technical path reference. Distribution and user names are examples; use the names on your own installation.

Use File Explorer for a small manual copy

In the Explorer address bar, enter the distribution share and navigate to the destination. You can also open Explorer from a WSL working directory:

explorer.exe .

If that command is unavailable, check whether Windows interoperability is enabled and whether the executable is on the inherited path. Do not blindly append a new PATH line on every failed attempt. First inspect the relevant configuration and try the known executable location if your Windows installation uses it:

command -v explorer.exe
printf '%s\n' "$PATH"

Do not edit Linux files by poking into the distribution’s raw package or VHDX storage. Use the supported share or WSL tools. A virtual disk is not a folder you can safely browse and edit as ordinary files.

Use cp for a straightforward one-time copy

Quote paths, especially Windows paths containing spaces. Make the destination explicit so a directory-copy result is easy to predict.

mkdir -p "$HOME/imported-project"
cp -v -- "/mnt/c/Users/YourName/Documents/config.txt" "$HOME/"
cp -R -- "/mnt/c/Users/YourName/Documents/project/." "$HOME/imported-project/"

The /. form copies the source directory’s contents, including hidden entries, into the named destination. cp -a attempts archive-style preservation on a capable destination. Windows-mounted filesystem behaviour can differ, so verify important metadata instead of assuming every copy method preserves it identically.

For one important file, compare content hashes after copying:

sha256sum -- "/mnt/c/Users/YourName/Documents/config.txt" "$HOME/config.txt"

Matching hashes establish matching file contents, not matching permissions, ownership, timestamps, or the correctness of the source file itself.

Use rsync for repeatable directory transfers

Install rsync through the distribution’s package manager if it is unavailable. Preview the operation before writing:

rsync -anvi -- "/mnt/c/Users/YourName/Documents/project/" "$HOME/project/"

Then perform the transfer when the preview shows the intended source and destination:

rsync -av --partial --progress -- "/mnt/c/Users/YourName/Documents/project/" "$HOME/project/"

The source trailing slash means “copy the contents.” Without it, rsync’s directory-placement semantics differ. The --partial option retains partial transfers; it is not a guarantee that every subsequent local copy resumes efficiently from exactly the interrupted byte. Local and remote transfers, quick checks, and partial-file options have different behaviour. Use the rsync manual when you need a particular resume strategy.

Exclude disposable material intentionally:

rsync -anvi \
  --exclude='node_modules/' \
  --exclude='__pycache__/' \
  --exclude='*.tmp' \
  -- "/mnt/c/Users/YourName/Documents/project/" "$HOME/project/"

Do not automatically exclude .git from a copy intended to preserve the whole repository. It contains history and repository metadata. An exclusion appropriate for deployment can be inappropriate for a backup.

Mirror deletion is a separate decision

Ordinary rsync does not delete extra destination files. --delete changes that. Preview deletions with itemised output, check both paths, and retain a recoverable copy when the destination contains valuable data.

rsync -anvi --delete -- "$HOME/project/" "/mnt/c/Users/YourName/project-copy/"

Removing -n makes the preview into a real operation. This is a mirror, not a versioned backup: a source deletion can remove the destination copy too. Do not run it against a broad destination such as your whole Documents directory.

Use tar when the Linux tree needs to remain intact

An archive stores a tree as a file and retains its structure and metadata for restoration onto a compatible Linux filesystem. It can also reduce the number of individual Windows-side file operations. Compression takes CPU time and may not help already compressed material; do not assume it is always faster.

mkdir -p "/mnt/c/Users/YourName/Backups"
tar -czf "/mnt/c/Users/YourName/Backups/project.tar.gz" -C "$HOME" project
tar -tzf "/mnt/c/Users/YourName/Backups/project.tar.gz"

mkdir -p "$HOME/restore-check"
tar -xzf "/mnt/c/Users/YourName/Backups/project.tar.gz" -C "$HOME/restore-check"

Using -C avoids embedding a leading home-directory path. A successful listing checks readability, but a restore and content comparison provide stronger evidence. Capture the command’s exit status; do not infer success from a few lines piped through head, which may show only the readable beginning of a damaged archive.

Fix line endings only when text actually needs it

A shebang error containing ^M often indicates CRLF in a script. Copying with cp, Explorer, rsync, or tar normally preserves those bytes. None should be advertised as a general line-ending repair.

file script.sh
sed -n '1l' script.sh

If it is a text script that should use LF, convert that file deliberately with an appropriate tool such as dos2unix, after preserving the source when needed. Do not bulk-convert binary files. A repository-level .gitattributes policy can make the intended text endings explicit for future checkouts.

Inspect permissions instead of resetting a whole tree

DrvFs permissions depend on Windows access rights, mount settings, and whether WSL metadata is enabled. “Every copied file becomes 777” is not a universal rule. Nor is “every Windows copy destroys every symlink.” The source, destination, options, and copy tool matter.

ls -ld -- "$HOME/project"
stat -- "$HOME/project/script.sh"
find "$HOME/project" -type l -print

If one intended executable lost its executable bit, restore that specific bit. Avoid blanket chmod 644 across a repository: that can break executable scripts. Avoid replacing ownership recursively unless you have established that ownership is actually wrong.

The Microsoft permission documentation explains metadata and Windows access restrictions. Merge any change into the existing /etc/wsl.conf; do not replace unrelated configuration. Restarting WSL to apply configuration also stops running work, so save it first.

Make a recurring copy observable

A scheduled sync must be able to find the source, destination, and mounted drive under the scheduled user’s environment. A directory named /mnt/c existing is not by itself proof that the drive is mounted. Inspect the mount and test the destination before relying on a scheduled task.

Log the rsync output and exit status, use absolute paths, and keep the job’s exclusions documented. WSL cron cannot be assumed to run while the distribution is stopped. If the schedule must start WSL from Windows, use a Windows task that invokes the intended distribution and script. Test the task under the same account and conditions as its future runs.

Measure the operation you actually need

Compare a representative tree, file count, bytes, source/destination filesystems, and elapsed time. A synthetic large zero-filled file does not predict a dependency tree containing many small files. Compression, caching, storage, background activity, and security scanning can all affect a result.

Use a uniquely named temporary destination, verify the result, and record the conditions. Do not declare Defender the cause solely because throughput falls below an invented MB/s threshold, or prescribe a broad security exclusion as the default fix. Profile the actual workload first.

Questions readers often ask

Which method preserves a Linux project best?

Use a compatible Linux destination with appropriate archive options, or a tar archive restored onto such a filesystem. Verify contents and the metadata that matter to your project.

Does rsync repair CRLF automatically?

No. A byte-preserving transfer retains the source line endings. Convert identified text files separately when required.

Is a mirror a backup?

Not necessarily. A mirror can reproduce deletions and damage. A recoverable backup needs retention and a tested restore.

Can I promise a fixed NVMe transfer speed?

No. Report an actual measurement with its workload and environment. Keep Linux work on the Linux side when appropriate, then test the relevant operation.

Share this post

Next Linux Swap Management: Supported Storage, ZFS Risks and Measured Tuning

Leave a comment

Your email address will not be published. Required fields are marked *