4

On Linux, if we move (rename) a file from one file system to another like this:

fs::rename("/src/a", "/dest/a")?;

is it possible the file /dest/a to become visible/available to other potential readers (processes that scan /dest/ for example) before the whole file data (contents) is fully copied to the destination file system?

kmdreko
  • 42,554
  • 6
  • 57
  • 106
at54321
  • 8,726
  • 26
  • 46
  • 3
    The thing `mv` does under-the-hood when the underlying syscall fails because the source and destination are on two different filesystems is what you need to do here: Create a temporary file on the destination filesystem, copy content into it, and then use `fs::rename` to atomically rename that temporary file to the destination name. – Charles Duffy Feb 01 '22 at 21:38
  • @CharlesDuffy Thanks a lot! I was wondering about how `mv` works, too. – at54321 Feb 01 '22 at 21:40

1 Answers1

4

From the docs

This will not work if the new name is on a different mount point.

So you shouldn't be using fs::rename to move between mount points. It's a simple filesystem rename and is not actually moving any data (which is why you can fs::rename a 2-terabyte file fairly quickly), so it only works if the source and destination are on the same filesystem.

If the source and destination are on the same mount point, then the answer is no. It's not possible for someone to read it before it's fully available, since, again, no data is actually transferred: it's just a single operation of "this pointer now points here and this one doesn't exist anymore".

Silvio Mayolo
  • 62,821
  • 6
  • 74
  • 116
  • 2
    Yes, you are right. Now I saw that restriction in the docs. So I guess Rust doesn't have a `move()` function and I should sequentially copy and delete? – at54321 Feb 01 '22 at 21:38