20

If I know the index node (inode) of a file, but I don't know its path (or any of its paths), is it possible to create a hard link to that inode directly?

I could find the file using sudo find / -inum 123546 and then create a hardlink, but that would be way too slow for my application.

N.B. I'm using an ext4 filesystem.

ibuprofen
  • 2,890
Astone
  • 201

2 Answers2

26

AFAIK, not with the kernel API. If such an interface existed, it would have to be limited to the super-user as otherwise that would let anyone access files in directories they don't have search access to.

But you could use debugfs on the file system (once it's unmounted) to do it (assuming you have write access to the block device).

debugfs -w /dev/block/device

(replace /dev/block/device with the actual block device the file system resides in).

Then, at the prompt of debugfs, enter

stat <123>
(with the angle brackets, replacing 123 with the actual inode number) to check that the file exists (inode has a link count greater than 0) and is not a directory.

If all good, enter:

ln <123> path/to/newfile
to create the hardlink (note that the path is relative to the root of the file system). Followed by:

mi <123>
to increment the link count (press Enter for all the fields except the link count where you'll want to add 1 to the current value).
  • 6
    Such an interface would also have to check that the file has a nonzero link count, otherwise it would be possible to resurrect a deleted-but-still-open file, which IIRC was rejected because it violates kernel invariants. – Gilles 'SO- stop being evil' Mar 12 '19 at 09:53
  • 2
    @Gilles related: https://unix.stackexchange.com/a/499760/308316 –  Mar 12 '19 at 10:16
  • 1
    @PhilipCouling, the execute permission bit on a directory translates to search permission. I already said in directories then don't have search access to. – Stéphane Chazelas Mar 12 '19 at 11:03
  • @StéphaneChazelas Yes I realise that. Though "search access" isn't self explanatory and the nomenclature is a touch misleading. For the sake of future readers, I think it's worth noting that that [search access / execute bit] infers restricted access to the children. This would help less experienced readers. It gives the logic in a single pass rather than forcing further google searches. – Philip Couling Mar 12 '19 at 11:17
  • Execute bit on a directory is usually referred to as "traversal". The word "search" instead suggests the ability to read the directory. – OrangeDog Mar 12 '19 at 13:22
  • 3
    @OrangeDog, search permission is the terminology used by the POSIX standard. – Stéphane Chazelas Mar 12 '19 at 14:28
  • 1
    @mosvy: That check can be removed from kernel. You have to patch up a couple of places in VFS for it to not hose itself though. I did it while working on my thesis years ago. – Joshua Mar 12 '19 at 15:19
3

Depending on your use case, another approach could be to first collect all file candidates in one directory by hard linking it and then hard linking the files you are particularly interested in.

Such as

mkdir -pm 0700 by-inode/{0..999}
find <path> ! -type d -printf "%i/%p\0" |
  while IFS=/ read -rd '' i n; do
    ln "$n" "by-inode/$((i/1000))/$i"
  done

(assuming your inode numbers are all less than 1,000,000, create more directories if need be).

Afterwards, your inodes are grouped 1000-wise and collected in the by-inode/ tree. From there, you can link them as needed.

Note though that it means that deleting files under <path> will not reclaim the space because of that extra hard link.

Toby Speight
  • 8,678
glglgl
  • 1,210