Are two subdirectories with the same root guaranteed to be on the same mounted file system?

They are not guaranteed that. It is possible that /foo/oldPath is a mount point.

This can, however, be easily checked by running mount | grep 'on /foo/oldPath' No output should indicate that the oldPath directory is not a mount point.

You will need to be more careful if you are using nested directories, since you can have a mount point anywhere.

I'm not sure whether this is automated, but it's worth noting that the 3rd field from mount (space-separated) is the mount point for each line, so utilizing an cut -d ' ' -f 3 could be used to extract the path (should you need to verify it's not just a substring of another mount point, like /foo/oldPath/nested/mountPoint)

If you'd like to translate this into C/C++ code, you may be able to use system("mount | grep 'on /foo/oldPath'"), but I won't swear by that. You may have better luck on StackOverflow for more implementation detail there if you need it.


You shouldn’t attempt this, for a variety of reasons (detailed in the other answers): /foo/oldPath could itself be a mountpoint, or an overlay file system could be present and prevent moving files. You can even encounter bind mounts, on single files, which will also cause problems when renaming files.

Instead of trying to determine ahead of time whether the files can be renamed, you should try to rename them and deal with the errors. rename will return -1 if an error occurs, and errno will be set to EXDEV if the rename isn’t possible because of cross-mount issues. You can then proceed in another fashion (copy and delete).

In general, to determine whether two file system objects are on the same file system, you should run stat on them and look at the device identifier (the st_dev field in struct stat). Two file system objects on the same file system will have the same device identifier.


Note that when you run on overlayfs, you cannot rely on rename() of pre-existing directories.

I think you could usually ignore this possibility, if you're not writing a general purpose file management tool... For example, a package manager... in which case you apparently might not consider it fixable (for atomicity reasons) and want to rely on the new redirect_dir format of overlayfs.

So this is more a pedantic note to let you know this is Linux, we don't comply with POSIX if we don't want to, and "guaranteed" is a very strong word :).


https://www.kernel.org/doc/Documentation/filesystems/overlayfs.txt

Unless "redirect_dir" feature is enabled, rename(2) on a lower or merged directory will fail with EXDEV.

Overlayfs already does not match usual expectations of a unix filesystem in other details:

Objects that are not directories (files, symlinks, device-special files etc.) are presented either from the upper or lower filesystem as appropriate. When a file in the lower filesystem is accessed in a way the requires write-access, such as opening for write access, changing some metadata etc., the file is first copied from the lower filesystem to the upper filesystem (copy_up)...

The copy_up operation essentially creates a new, identical file and moves it over to the old name. Any open files referring to this inode will access the old data.