Is it possible to rename a file or directory using the inode?
You can rename a file (directory or whatever) using only knowledge of the inode using find
, but if (a) the filesystem containing it is not mounted, or if (b) there is another filesystem mounted over a non-empty directory that contains the file you are interested in, the file is simply not accessible by your system. In case (a), you need to mount the filesystem before you can do anything to the contents, including renaming, and in case (b), you need to unmount the filesystem which is mounted "over the top of" the directory containing the file you want to rename. It looks like you are asking about case (b).
If I understand you correctly, you are trying to make your old /home
directory (which is located on your root partition) accessible, while still using your new partition mounted at /home
. If that's what you want, do the following:
Close all files and log out. Then log in as root
(use a virtual terminal for this—press Ctrl-Alt-F2) Run the following:
umount /home
mv /home /home-old
mkdir /home
mount -a
ls /home
ls /home-old
If all is well, log out and log back in as yourself and all should be fine.
Incidentally, the command to rename a file using only knowledge of its inode (assuming the file is in the current directory) is:
find . -maxdepth 1 -inum 123456789 -exec mv {} mynewname \;
Where 123456789
is the inode number, of course. (Note that find
determines the filename and its path and passes this info to mv
; there is no way at all to rename a file without involving the existing filename in any way, but if it's just that you don't know the filename, it is quite simple.)
In a typical Unix filesystem, it's structurally impossible in general to move a file based on the inode. The reason is that renaming a file means removing its directory entry from the directory that contains it, and creating a directory elsewhere. But the inode doesn't contain a pointer to the directory entry, it only contains (pointers to) the file metadata (timestamps, permissions, etc.) and the file contents.
For a file with multiple hard links, which of these would you be renaming? The inode isn't enough information.
For a directory, on some filesystems, it would be possible to act given the inode alone:
- Read the content of the directory, which is definitely reachable from the inode.
- Locate the directory entry for
..
. This points to the parent directory. - In the parent directory, look for a directory entry with the right inode number.
This makes several assumptions, however:
- What if there are multiple entries for the same inode? Actually, that's not a problem: that'll hardly ever happen in practice since most unix variants forbid explicit hard links to directories.
- Does
..
exist in the first place? This depends on the filesystem type. Some filesystems have an explicit entry for..
; for others, these entries are faked by the filesystem driver. If..
doesn't exist, this approach is fundamentally impossible. - Even if the filesystem does include
..
links, there's another stumbling block which might not be obvious: step 1 may be possible inside the kernel, but there's no interface for it. Many unix variants have no interface that allows opening a file via its inode, because that would bypass permissions. For example, a file with permissionsrwxr-xr-x
(i.e. world-readable) that's located in a directory with permissionsrwx------
(i.e. accessible only to its owner) is not accesible to anyone but the directory owner. This can't be determined from the inode alone — the file could actually be accessible through another hard link!
The upshot is that no, it isn't possible to do anything, including renaming, with a file given only its inode. You need to have a path to the file.
The only practical way to act on a file given its inode is to first find a path, for example with find -inum
, and then use the path to act. That doesn't help in your situation, where the file is shadowed by a mount point. There's no portable way to access files shadowed by a mount point; on Linux, as you've discovered, you can use a bind mount.