Skip to content

Commit 8b36a29

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 <dsterba@suse.com>
1 parent 07b8c74 commit 8b36a29

File tree

2 files changed

+24
-3
lines changed

2 files changed

+24
-3
lines changed

mkfs/rootdir.c

Lines changed: 18 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,9 @@ static struct rootdir_path current_path = {
9090
.level = 0,
9191
};
9292

93+
/* Track if a hardlink was found and a warning was printed. */
94+
static bool g_hardlink_warning;
95+
static u64 g_hardlink_count;
9396
static struct btrfs_trans_handle *g_trans = NULL;
9497

9598
static inline struct inode_entry *rootdir_path_last(struct rootdir_path *path)
@@ -428,9 +431,14 @@ static int ftw_add_inode(const char *full_path, const struct stat *st,
428431
* On most filesystems st_nlink of a directory is the number of
429432
* subdirs, including "." and "..", so skip directory inodes.
430433
*/
431-
if (unlikely(!S_ISDIR(st->st_mode) && st->st_nlink > 1))
432-
warning("'%s' has extra hard links, they will be converted into new inodes",
433-
full_path);
434+
if (unlikely(!S_ISDIR(st->st_mode) && st->st_nlink > 1)) {
435+
if (!g_hardlink_warning) {
436+
warning("'%s' has extra hardlinks, they will be converted into new inodes",
437+
full_path);
438+
g_hardlink_warning = true;
439+
}
440+
g_hardlink_count++;
441+
}
434442

435443
/* The rootdir itself. */
436444
if (unlikely(ftwbuf->level == 0)) {
@@ -612,6 +620,8 @@ int btrfs_mkfs_fill_dir(const char *source_dir, struct btrfs_root *root)
612620
}
613621

614622
g_trans = trans;
623+
g_hardlink_warning = false;
624+
g_hardlink_count = 0;
615625
INIT_LIST_HEAD(&current_path.inode_list);
616626

617627
ret = nftw(source_dir, ftw_add_inode, 32, FTW_PHYS);
@@ -625,6 +635,11 @@ int btrfs_mkfs_fill_dir(const char *source_dir, struct btrfs_root *root)
625635
error_msg(ERROR_MSG_COMMIT_TRANS, "%m");
626636
goto out;
627637
}
638+
639+
if (g_hardlink_warning)
640+
warning("%llu hardlinks were detected in %s, all converted to new inodes",
641+
g_hardlink_count, source_dir);
642+
628643
while (current_path.level > 0)
629644
rootdir_path_pop(&current_path);
630645

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

Lines changed: 6 additions & 0 deletions
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)