btrfs-progs: mkfs: warn about hard links with --rootdir

The recent rework changes how we detect hard links.

[OLD BEHAVIOR]
We trusted st_nlink and st_ino, reuse them without extra sanity
checks.

That behavior has problems handling cross mount-point or hard links out
of the rootdir cases.

[NEW BEHAVIOR]
The new refactored code will treat every inode, no matter if it's a
hardlink, as a new inode.

This means we will break the hard link detection, and every hard link
will be created as a different inode.

For the most common use case, like populating a rootfs, it's totally
fine.

[EXTRA WARNING]
But for cases where the user have extra hard links inside the rootdir,
output a warning just to inform the end user.

This will not cause any content difference, just breaking the hard links
into new inodes.

Signed-off-by: Qu Wenruo <wqu@suse.com>
This commit is contained in:
Qu Wenruo 2024-07-31 18:39:22 +09:30 committed by David Sterba
parent c6464d3f99
commit 27974edb4d

View File

@ -417,6 +417,21 @@ static int ftw_add_inode(const char *full_path, const struct stat *st,
u64 ino;
int ret;
/*
* Hard link needs extra detection code, not supported for now, but
* it's not to break anything but splitting the hard links into new
* inodes. And we do not even know if the hard links are inside the
* rootdir.
*
* So here we only need to do extra warning.
*
* On most filesystems st_nlink of a directory is the number of
* subdirs, including "." and "..", so skip directory inodes.
*/
if (unlikely(!S_ISDIR(st->st_mode) && st->st_nlink > 1))
warning("'%s' has extra hard links, they will be converted into new inodes",
full_path);
/* The rootdir itself. */
if (unlikely(ftwbuf->level == 0)) {
u64 root_ino = btrfs_root_dirid(&root->root_item);