mv within the same filesystem is atomic for each file, but across filesystem, it's a much more complex operation (assuming that you're only moving regular files and that the destinations don't exist initially):
- Remove the destination file if it exists.
- Open the source file for reading. Some implementations may perform this before the previous step.
- Create the destination file. Some implementations may truncate it if it exists at that point. Some implementations may perform this before the previous step.
- Read some data from the source file and write it to the destination file.
- Replicate the metadata of the source file on the destination file. Some implementations may perform part or all of this after the next step.
- Close the source file and the destination file.
- Remove the source file.
For the most part, if two
mv processes attempt to move the same file at the same time, they'll both copy the data: the instance first to start will create a file, the second instance will delete that file and create a new one. However, if you're unlucky, it is possible to lose data. For example:
- Instance 1 performs the copy and closes the two files (steps 1–6).
- At that point, instance 2 reaches this file and removes the destination (step 1), but is preempted before it can open the source file.
- Instance 1 proceeds to remove the source file (step 7).
- Instance 2 goes on to step 2, but the file no longer exists.
I think that if a file is present at the destination, it will have the correct content. But as we've seen, it is possible for a file to disappear.