Skip to content

Commit

Permalink
btrfs-progs: tests: add hardlink related tests for mkfs --subvol
Browse files Browse the repository at this point in the history
This introduces two new cases:

- 3 hardlinks without any subvolume
  This should results 3 hard links inside the btrfs.

- 3 hardlinks, but a subvolume will split 2 of them
  Then the 2 inside the same subvolume should still report 2 nlinks,
  but the lone one inside the new subvolume can only report 1 nlink.

Signed-off-by: Qu Wenruo <[email protected]>
  • Loading branch information
adam900710 authored and kdave committed Sep 17, 2024
1 parent ef11574 commit 5ff9f62
Show file tree
Hide file tree
Showing 2 changed files with 68 additions and 18 deletions.
8 changes: 3 additions & 5 deletions mkfs/rootdir.c
Original file line number Diff line number Diff line change
Expand Up @@ -725,7 +725,7 @@ static int ftw_add_inode(const char *full_path, const struct stat *st,
parent = rootdir_path_last(&current_path);
root = parent->root;

/* For non-directory inode, check if there is already any hard link. */
/* Check if there is already a hard link record for this. */
if (have_hard_links) {
struct hardlink_entry *found;

Expand Down Expand Up @@ -771,6 +771,7 @@ static int ftw_add_inode(const char *full_path, const struct stat *st,
error("failed to insert inode item %llu for '%s': %m", ino, full_path);
return ret;
}

ret = btrfs_add_link(g_trans, root, ino, parent->ino,
full_path + ftwbuf->base,
strlen(full_path) - ftwbuf->base,
Expand All @@ -782,10 +783,7 @@ static int ftw_add_inode(const char *full_path, const struct stat *st,
return ret;
}

/*
* Found a possible hard link, add it into the hard link rb tree for
* future detection.
*/
/* Record this new hard link. */
if (have_hard_links) {
ret = add_hard_link(root, ino, st);
if (ret < 0) {
Expand Down
78 changes: 65 additions & 13 deletions tests/mkfs-tests/036-rootdir-subvol/test.sh
Original file line number Diff line number Diff line change
Expand Up @@ -11,23 +11,75 @@ prepare_test_dev

tmp=$(_mktemp_dir mkfs-rootdir)

run_check touch "$tmp/foo"
run_check mkdir "$tmp/dir"
run_check mkdir "$tmp/dir/subvol"
run_check touch "$tmp/dir/subvol/bar"
basic()
{
run_check touch "$tmp/foo"
run_check mkdir "$tmp/dir"
run_check mkdir "$tmp/dir/subvol"
run_check touch "$tmp/dir/subvol/bar"

run_check_mkfs_test_dev --rootdir "$tmp" --subvol dir/subvol
run_check $SUDO_HELPER "$TOP/btrfs" check "$TEST_DEV"
run_check_mkfs_test_dev --rootdir "$tmp" --subvol dir/subvol
run_check $SUDO_HELPER "$TOP/btrfs" check "$TEST_DEV"

run_check_mount_test_dev
run_check_stdout $SUDO_HELPER "$TOP/btrfs" subvolume list "$TEST_MNT" | \
run_check_mount_test_dev
run_check_stdout $SUDO_HELPER "$TOP/btrfs" subvolume list "$TEST_MNT" | \
cut -d\ -f9 > "$tmp/output"
run_check_umount_test_dev
run_check_umount_test_dev

result=$(cat "$tmp/output")
result=$(cat "$tmp/output")

if [ "$result" != "dir/subvol" ]; then
_fail "dir/subvol not in subvolume list"
fi
if [ "$result" != "dir/subvol" ]; then
_fail "dir/subvol not in subvolume list"
fi
rm -rf -- "$tmp/foo" "$tmp/dir"
}

basic_hardlinks()
{
run_check touch "$tmp/hl1"
run_check ln "$tmp/hl1" "$tmp/hl2"
run_check mkdir "$tmp/dir"
run_check ln "$tmp/hl1" "$tmp/dir/hl3"

run_check_mkfs_test_dev --rootdir "$tmp"
run_check $SUDO_HELPER "$TOP/btrfs" check "$TEST_DEV"

run_check_mount_test_dev
nr_hardlink=$(run_check_stdout $SUDO_HELPER stat -c "%h" "$TEST_MNT/hl1")

if [ "$nr_hardlink" -ne 3 ]; then
_fail "hard link number incorrect, has ${nr_hardlink} expect 3"
fi
run_check_umount_test_dev
rm -rf -- "$tmp/hl1" "$tmp/hl2" "$tmp/dir"
}

split_by_subvolume_hardlinks()
{
run_check touch "$tmp/hl1"
run_check ln "$tmp/hl1" "$tmp/hl2"
run_check mkdir "$tmp/subv"
run_check ln "$tmp/hl1" "$tmp/subv/hl3"

run_check_mkfs_test_dev --rootdir "$tmp" --subvol subv
run_check $SUDO_HELPER "$TOP/btrfs" check "$TEST_DEV"

run_check_mount_test_dev
nr_hardlink=$(run_check_stdout $SUDO_HELPER stat -c "%h" "$TEST_MNT/hl1")

if [ "$nr_hardlink" -ne 2 ]; then
_fail "hard link number incorrect for hl1, has ${nr_hardlink} expect 2"
fi

nr_hardlink=$(run_check_stdout $SUDO_HELPER stat -c "%h" "$TEST_MNT/subv/hl3")
if [ "$nr_hardlink" -ne 1 ]; then
_fail "hard link number incorrect for subv/hl3, has ${nr_hardlink} expect 1"
fi
run_check_umount_test_dev
rm -rf -- "$tmp/hl1" "$tmp/hl2" "$tmp/dir"
}

basic
basic_hardlinks
split_by_subvolume_hardlinks
rm -rf -- "$tmp"

0 comments on commit 5ff9f62

Please sign in to comment.