mirror_zfs/tests/zfs-tests/tests/functional/fallocate/fallocate_prealloc.ksh
adilger f734301d22
linux: add basic fallocate(mode=0/2) compatibility
Implement semi-compatible functionality for mode=0 (preallocation)
and mode=FALLOC_FL_KEEP_SIZE (preallocation beyond EOF) for ZPL.

Since ZFS does COW and snapshots, preallocating blocks for a file
cannot guarantee that writes to the file will not run out of space.
Even if the first overwrite was guaranteed, it would not handle any
later overwrite of blocks due to COW, so strict compliance is futile.
Instead, make a best-effort check that at least enough free space is
currently available in the pool (with a bit of margin), then create
a sparse file of the requested size and continue on with life.

This does not handle all cases (e.g. several fallocate() calls before
writing into the files when the filesystem is nearly full), which
would require a more complex mechanism to be implemented, probably
based on a modified version of dmu_prealloc(), but is usable as-is.

A new module option zfs_fallocate_reserve_percent is used to control
the reserve margin for any single fallocate call.  By default, this
is 110% of the requested preallocation size, so an additional 10% of
available space is reserved for overhead to allow the application a
good chance of finishing the write when the fallocate() succeeds.
If the heuristics of this basic fallocate implementation are not
desirable, the old non-functional behavior of returning EOPNOTSUPP
for calls can be restored by setting zfs_fallocate_reserve_percent=0.

The parameter of zfs_statvfs() is changed to take an inode instead
of a dentry, since no dentry is available in zfs_fallocate_common().

A few tests from @behlendorf cover basic fallocate functionality.

Reviewed-by: Richard Laager <rlaager@wiktel.com>
Reviewed-by: Arshad Hussain <arshad.super@gmail.com>
Reviewed-by: Matthew Ahrens <mahrens@delphix.com>
Co-authored-by: Brian Behlendorf <behlendorf1@llnl.gov>
Signed-off-by: Andreas Dilger <adilger@dilger.ca>
Issue #326
Closes #10408
2020-06-18 11:22:11 -07:00

64 lines
1.7 KiB
Bash
Executable File

#!/bin/ksh -p
#
# CDDL HEADER START
#
# The contents of this file are subject to the terms of the
# Common Development and Distribution License (the "License").
# You may not use this file except in compliance with the License.
#
# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
# or http://www.opensolaris.org/os/licensing.
# See the License for the specific language governing permissions
# and limitations under the License.
#
# When distributing Covered Code, include this CDDL HEADER in each
# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
# If applicable, add the following below this CDDL HEADER, with the
# fields enclosed by brackets "[]" replaced with your own identifying
# information: Portions Copyright [yyyy] [name of copyright owner]
#
# CDDL HEADER END
#
#
# Copyright (c) 2020 by Lawrence Livermore National Security, LLC.
#
. $STF_SUITE/include/libtest.shlib
#
# DESCRIPTION:
# Test fallocate(2) preallocation.
#
# STRATEGY:
# 1. Verify mode 0 fallocate is supported.
# 2. Verify default 10% reserve space is honored by setting a quota.
#
verify_runnable "global"
FILE=$TESTDIR/$TESTFILE0
function cleanup
{
log_must zfs set quota=none $TESTPOOL
[[ -e $TESTDIR ]] && log_must rm -Rf $TESTDIR/*
}
log_assert "Ensure sparse files can be preallocated"
log_onexit cleanup
# Pre-allocate a sparse 1GB file.
log_must fallocate -l $((1024 * 1024 * 1024)) $FILE
log_must rm -Rf $TESTDIR/*
# Verify that an additional ~10% reserve space is required.
log_must zfs set quota=100M $TESTPOOL
log_mustnot fallocate -l $((150 * 1024 * 1024)) $FILE
log_mustnot fallocate -l $((110 * 1024 * 1024)) $FILE
log_must fallocate -l $((90 * 1024 * 1024)) $FILE
log_pass "Ensure sparse files can be preallocated"