Page MenuHomeFreeBSD

D60439.id188968.diff
No OneTemporary

D60439.id188968.diff

diff --git a/usr.sbin/makefs/tests/makefs_zfs_tests.sh b/usr.sbin/makefs/tests/makefs_zfs_tests.sh
--- a/usr.sbin/makefs/tests/makefs_zfs_tests.sh
+++ b/usr.sbin/makefs/tests/makefs_zfs_tests.sh
@@ -550,6 +550,59 @@
common_cleanup
}
+#
+# Make sure that the link count and the size of the directories which are the
+# roots of datasets count "." and the directories which are the mountpoints
+# of other datasets. fts(3) trusts the link count of the directories of ZFS
+# and skips the subdirectories that it does not account for.
+#
+atf_test_case dataset_link_counts cleanup
+dataset_link_counts_body()
+{
+ local dir entries subdirs
+
+ create_test_dirs
+ cd $TEST_INPUTS_DIR
+
+ mkdir -p dir1/sub1 dir1/sub2 dir1/dir2/sub3 dir1/dir2/dir3 dir4
+ echo a > dir1/a
+ echo b > dir1/dir2/b
+ echo c > dir1/sub1/c
+ echo d > dir1/sub2/d
+ echo e > dir1/dir2/sub3/e
+
+ cd -
+
+ atf_check $MAKEFS -s 1g -o rootpath=/ -o poolname=$ZFS_POOL_NAME \
+ -o fs=${ZFS_POOL_NAME}/dir1 -o fs=${ZFS_POOL_NAME}/dir1/dir2 \
+ -o fs=${ZFS_POOL_NAME}/dir1/dir2/dir3 -o fs=${ZFS_POOL_NAME}/dir4 \
+ -o fs=${ZFS_POOL_NAME}/dir5 \
+ $TEST_IMAGE $TEST_INPUTS_DIR
+
+ import_image
+
+ # find(1) relies on the link counts to decide which entries may be
+ # directories, so it must see the whole tree.
+ (cd $TEST_INPUTS_DIR && find dir1 dir4 | sort) > ./expected
+ atf_check -o file:./expected -x \
+ "cd $TEST_MOUNT_DIR && find dir1 dir4 | sort"
+
+ # The link count is the number of directories in the directory plus
+ # "." and "..", and the size is the number of entries plus the same.
+ for dir in . dir1 dir1/sub1 dir1/dir2 dir1/dir2/dir3 dir4 dir5; do
+ subdirs=$(ls -d $TEST_MOUNT_DIR/$dir/*/ 2>/dev/null | wc -l)
+ entries=$(ls -A $TEST_MOUNT_DIR/$dir | wc -l)
+ atf_check -o inline:$((subdirs + 2))\\n \
+ stat -f %l $TEST_MOUNT_DIR/$dir
+ atf_check -o inline:$((entries + 2))\\n \
+ stat -f %z $TEST_MOUNT_DIR/$dir
+ done
+}
+dataset_link_counts_cleanup()
+{
+ common_cleanup
+}
+
#
# Create a pool with two datasets, where the root dataset is mounted below
# the child dataset.
@@ -1112,6 +1165,7 @@
atf_add_test_case autoexpand
atf_add_test_case basic
atf_add_test_case compression
+ atf_add_test_case dataset_link_counts
atf_add_test_case dataset_removal
atf_add_test_case devfs
atf_add_test_case empty_dir
diff --git a/usr.sbin/makefs/zfs/fs.c b/usr.sbin/makefs/zfs/fs.c
--- a/usr.sbin/makefs/zfs/fs.c
+++ b/usr.sbin/makefs/zfs/fs.c
@@ -389,10 +389,11 @@
* The size of a ZPL directory is the number of entries
* (including "." and ".."), and the link count is the
* number of entries which are directories
- * (including "." and "..").
+ * (including "." and ".."). The root of a dataset is
+ * the "." node itself, followed by the other entries.
*/
- for (fsnode *c =
- fsnode_isroot(cur) ? cur->next : cur->child;
+ for (const fsnode *c =
+ fsnode_isroot(cur) ? cur : cur->child;
c != NULL; c = c->next) {
switch (c->type) {
case S_IFDIR:

File Metadata

Mime Type
text/plain
Expires
Thu, Oct 8, 10:37 PM (8 h, 16 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
40447956
Default Alt Text
D60439.id188968.diff (2 KB)

Event Timeline