aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--module/zfs/zfs_vfsops.c2
-rw-r--r--tests/runfiles/linux.run3
-rw-r--r--tests/zfs-tests/tests/functional/no_space/Makefile.am3
-rwxr-xr-xtests/zfs-tests/tests/functional/no_space/enospc_df.ksh73
4 files changed, 79 insertions, 2 deletions
diff --git a/module/zfs/zfs_vfsops.c b/module/zfs/zfs_vfsops.c
index 205773ef3..74f444ebf 100644
--- a/module/zfs/zfs_vfsops.c
+++ b/module/zfs/zfs_vfsops.c
@@ -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 */
diff --git a/tests/runfiles/linux.run b/tests/runfiles/linux.run
index 0b41d087b..d3ecf6274 100644
--- a/tests/runfiles/linux.run
+++ b/tests/runfiles/linux.run
@@ -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]
diff --git a/tests/zfs-tests/tests/functional/no_space/Makefile.am b/tests/zfs-tests/tests/functional/no_space/Makefile.am
index a5b042b23..c2e42bc2a 100644
--- a/tests/zfs-tests/tests/functional/no_space/Makefile.am
+++ b/tests/zfs-tests/tests/functional/no_space/Makefile.am
@@ -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
index 000000000..b3df69141
--- /dev/null
+++ b/tests/zfs-tests/tests/functional/no_space/enospc_df.ksh
@@ -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."