]> granicus.if.org Git - zfs/commitdiff
zfs filesystem skipped by df -h
authorPaul Zuchowski <31706010+PaulZ-98@users.noreply.github.com>
Sun, 13 Jan 2019 18:06:13 +0000 (13:06 -0500)
committerBrian Behlendorf <behlendorf1@llnl.gov>
Sun, 13 Jan 2019 18:06:13 +0000 (10:06 -0800)
On full pool when pool root filesystem references very few bytes,
the f_blocks returned to statvfs is 0 but should be at least 1.

Reviewed by: Tom Caputi <tcaputi@datto.com>
Reviewed-by: Brian Behlendorf <behlendorf1@llnl.gov>
Signed-off-by: Paul Zuchowski <pzuchowski@datto.com>
Closes #8253
Closes #8254

module/zfs/zfs_vfsops.c
tests/runfiles/linux.run
tests/zfs-tests/tests/functional/no_space/Makefile.am
tests/zfs-tests/tests/functional/no_space/enospc_df.ksh [new file with mode: 0755]

index 205773ef35d7835286cd4d96fa74d31d1d9136f0..74f444ebfb91280dc50332dfa20277b6cb68981a 100644 (file)
@@ -1449,6 +1449,8 @@ zfs_statvfs(struct dentry *dentry, struct kstatfs *statp)
         * "preferred" size.
         */
 
+       /* Round up so we never have a filesytem using 0 blocks. */
+       refdbytes = P2ROUNDUP(refdbytes, statp->f_bsize);
        statp->f_blocks = (refdbytes + availbytes) >> bshift;
        statp->f_bfree = availbytes >> bshift;
        statp->f_bavail = statp->f_bfree; /* no root reservation */
index 0b41d087b2dbaf69cb22634f6607acb916209540..d3ecf6274770cbbcb8716354c5aade32160afcf8 100644 (file)
@@ -656,7 +656,8 @@ tests = ['nestedfs_001_pos']
 tags = ['functional', 'nestedfs']
 
 [tests/functional/no_space]
-tests = ['enospc_001_pos', 'enospc_002_pos', 'enospc_003_pos']
+tests = ['enospc_001_pos', 'enospc_002_pos', 'enospc_003_pos',
+    'enospc_df']
 tags = ['functional', 'no_space']
 
 [tests/functional/nopwrite]
index a5b042b23ad0504b01e83914a3eb3785691bb3b3..c2e42bc2ada4ed475f313c15da493f6ca734f114 100644 (file)
@@ -4,7 +4,8 @@ dist_pkgdata_SCRIPTS = \
        cleanup.ksh \
        enospc_001_pos.ksh \
        enospc_002_pos.ksh \
-       enospc_003_pos.ksh
+       enospc_003_pos.ksh \
+       enospc_df.ksh
 
 dist_pkgdata_DATA = \
        enospc.cfg
diff --git a/tests/zfs-tests/tests/functional/no_space/enospc_df.ksh b/tests/zfs-tests/tests/functional/no_space/enospc_df.ksh
new file mode 100755 (executable)
index 0000000..b3df691
--- /dev/null
@@ -0,0 +1,73 @@
+#!/bin/ksh -p
+#
+# CDDL HEADER START
+#
+# This file and its contents are supplied under the terms of the
+# Common Development and Distribution License ("CDDL"), version 1.0.
+# You may only use this file in accordance with the terms of version
+# 1.0 of the CDDL.
+#
+# A full copy of the text of the CDDL should have accompanied this
+# source.  A copy of the CDDL is also available via the Internet at
+# http://www.illumos.org/license/CDDL.
+#
+# CDDL HEADER END
+#
+
+#
+# Copyright (c) 2014, 2016 by Delphix. All rights reserved.
+# Copyright (c) 2019 by Datto Inc. All rights reserved.
+#
+
+. $STF_SUITE/include/libtest.shlib
+. $STF_SUITE/tests/functional/no_space/enospc.cfg
+
+#
+# DESCRIPTION:
+# After filling a filesystem, the df command produces the
+# expected result against the pool root filesystem.
+#
+# STRATEGY:
+# 1. Write a file until the child file system is full.
+# 2. Ensure that ENOSPC is returned.
+# 3. Unmount the child file system.
+# 4. Issue df -h command.
+# 5. Ensure pool root filesystem is included (issue #8253).
+# 6. Issue df -h <filesystem>.
+# 7. Ensure size and used are non-zero.
+#
+
+verify_runnable "both"
+
+log_onexit default_cleanup_noexit
+
+log_assert "Correct df output is returned when file system is full."
+
+default_setup_noexit $DISK_SMALL
+log_must zfs set compression=off $TESTPOOL/$TESTFS
+
+log_note "Writing file: $TESTFILE0 until ENOSPC."
+file_write -o create -f $TESTDIR/$TESTFILE0 -b $BLOCKSZ \
+    -c $NUM_WRITES -d $DATA
+ret=$?
+
+(( $ret != $ENOSPC )) && \
+    log_fail "$TESTFILE0 returned: $ret rather than ENOSPC."
+
+log_must zfs umount $TESTPOOL/$TESTFS
+
+# Ensure the pool root filesystem shows in df output.
+# If the pool was full (available == 0) and the pool
+# root filesytem had very little in it (used < 1 block),
+# the size reported to df was zero (issue #8253) and
+# df skipped the filesystem in its output.
+log_must eval "df -h | grep $TESTPOOL"
+
+# Confirm df size and used are non-zero.
+size=$(df -h /$TESTPOOL | grep $TESTPOOL | awk '{print $2}')
+used=$(df -h /$TESTPOOL | grep $TESTPOOL | awk '{print $3}')
+if [[ "$size" = "0" ]] || [[ "$used" = "0" ]]
+then
+       log_fail "df failed with size $size and used $used."
+fi
+log_pass "df after ENOSPC works as expected."