Skip to content

Commit 269d106

Browse files
committed
btrfs-progs: mkfs: print only first warning when --rootdir finds a hardlink
There's a report that newly added --rootdir print too many warnings for hardlinks, which is maybe not that uncommon. We still want to let the user know about that so print it just once and count how many were found: $ mkfs.btrfs --rootdir ... WARNING: '/tmp/btrfs-progs-mkfs-rootdir-hardlinks.7RcdfR/rootdir/inside_link' has extra hardlinks, they will be converted into new inodes WARNING: 12 hardlinks were detected in /tmp/btrfs-progs-mkfs-rootdir-hardlinks.7RcdfR/rootdir, all converted to new inodes Link: #872 (comment) Signed-off-by: David Sterba <[email protected]>
1 parent 4636c58 commit 269d106

File tree

2 files changed

+24
-3
lines changed

2 files changed

+24
-3
lines changed

mkfs/rootdir.c

+18-3
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,9 @@ static struct rootdir_path current_path = {
9393
.level = 0,
9494
};
9595

96+
/* Track if a hardlink was found and a warning was printed. */
97+
static bool g_hardlink_warning;
98+
static u64 g_hardlink_count;
9699
static struct btrfs_trans_handle *g_trans = NULL;
97100
static struct list_head *g_subvols;
98101
static u64 next_subvol_id = BTRFS_FIRST_FREE_OBJECTID;
@@ -509,9 +512,14 @@ static int ftw_add_inode(const char *full_path, const struct stat *st,
509512
* On most filesystems st_nlink of a directory is the number of
510513
* subdirs, including "." and "..", so skip directory inodes.
511514
*/
512-
if (unlikely(!S_ISDIR(st->st_mode) && st->st_nlink > 1))
513-
warning("'%s' has extra hard links, they will be converted into new inodes",
514-
full_path);
515+
if (unlikely(!S_ISDIR(st->st_mode) && st->st_nlink > 1)) {
516+
if (!g_hardlink_warning) {
517+
warning("'%s' has extra hardlinks, they will be converted into new inodes",
518+
full_path);
519+
g_hardlink_warning = true;
520+
}
521+
g_hardlink_count++;
522+
}
515523

516524
/* The rootdir itself. */
517525
if (unlikely(ftwbuf->level == 0)) {
@@ -707,13 +715,20 @@ int btrfs_mkfs_fill_dir(struct btrfs_trans_handle *trans, const char *source_dir
707715

708716
g_trans = trans;
709717
g_subvols = subvols;
718+
g_hardlink_warning = false;
719+
g_hardlink_count = 0;
710720
INIT_LIST_HEAD(&current_path.inode_list);
711721

712722
ret = nftw(source_dir, ftw_add_inode, 32, FTW_PHYS);
713723
if (ret) {
714724
error("unable to traverse directory %s: %d", source_dir, ret);
715725
return ret;
716726
}
727+
728+
if (g_hardlink_warning)
729+
warning("%llu hardlinks were detected in %s, all converted to new inodes",
730+
g_hardlink_count, source_dir);
731+
717732
while (current_path.level > 0)
718733
rootdir_path_pop(&current_path);
719734

tests/mkfs-tests/034-rootdir-extra-hard-links/test.sh

+6
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,12 @@ run_check mkdir "$tmpdir/rootdir"
1313
run_check touch "$tmpdir/rootdir/inside_link"
1414
run_check ln "$tmpdir/rootdir/inside_link" "$tmpdir/outside_link"
1515

16+
# Add more links to trigger the warnings
17+
run_check touch "$tmpdir/rootdir/link0"
18+
for i in {1..10}; do
19+
run_check ln "$tmpdir/rootdir/link0" "$tmpdir/rootdir/link$i"
20+
done
21+
1622
run_check_mkfs_test_dev --rootdir "$tmpdir/rootdir"
1723

1824
# For older mkfs.btrfs --rootdir we will create inside_link with 2 links,

0 commit comments

Comments
 (0)