On 23/12/2025 00:08, Andrei Topala wrote:
Is there a downside to always trying rename() first and doing the copy

if it fails? That's approximately what toybox's mv does...


mv already tries rename() first. The problem is that rename() returns

EXDEV even when source and destination are on the same physical device

but accessed through different bind mount points.


For example, with these bind mounts on the same device:


   /mnt/full      root=/

   /mnt/data      root=/data


Moving /mnt/data/file to /mnt/full/backup/ fails with EXDEV because the

kernel sees different mount points, forcing an unnecessary copy+delete.


[1] solves this by iterating through all mount/realpath combinations

until rename() succeeds. I've implemented an approach using gnulib's

mountlist.h [2].


I'm thinking of:

1. Parse /proc/self/mountinfo via read_file_system_list()

2. Find mount entries for source and destination paths

3. If different me_dev, fall back to copy (truly different devices)

4. Compute device_path = me_mntroot + path_relative_to_mountpoint

5. Translate one path through the other's mount:

    - If dst's device_path is under src_mount's root, translate dst

    - Otherwise translate src through dst_mount

6. rename() with translated path succeeds - both paths now resolve

      through the same mount point


Example translation:

   /mnt/data/file

   → mount: root="/data", mountdir="/mnt/data"

   → device_path: /data/file

   → through /mnt/full (root="/"): /mnt/full/data/file



   rename("/mnt/full/data/file", "/mnt/full/backup/file") succeeds


This avoids the brute-force iteration in [1] by computing which mount

can "see" both paths (the one with the wider root).


I haven't signed FSF copyright assignment yet but am willing to do so

if there's interest.


[1] https://github.com/milahu/move-files-across-bind-mounts

[2]
https://github.com/coreutils/coreutils/commit/a961fc317951b92c2468771f8a0d2895e94ac2a3

Referencing the original discussion:
https://lists.gnu.org/archive/html/coreutils/2024-12/msg00002.html
The code is good, and thanks for talking time to propose a solution.
However my conclusion from the original thread is still the same.
I don't think it's appropriate for mv to do this expensive/error prone
path manipulation for each file being copied across devices.
IMHO this is more appropriate for the kernel,
which has a more holistic view of the mount space.

thanks,
Padraig.



Reply via email to