1#!/bin/ksh -p
2#
3# CDDL HEADER START
4#
5# The contents of this file are subject to the terms of the
6# Common Development and Distribution License (the "License").
7# You may not use this file except in compliance with the License.
8#
9# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10# or http://www.opensolaris.org/os/licensing.
11# See the License for the specific language governing permissions
12# and limitations under the License.
13#
14# When distributing Covered Code, include this CDDL HEADER in each
15# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16# If applicable, add the following below this CDDL HEADER, with the
17# fields enclosed by brackets "[]" replaced with your own identifying
18# information: Portions Copyright [yyyy] [name of copyright owner]
19#
20# CDDL HEADER END
21#
22
23#
24# Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
25# Use is subject to license terms.
26#
27
28#
29# Copyright (c) 2013, 2016 by Delphix. All rights reserved.
30#
31
32. $STF_SUITE/include/libtest.shlib
33
34#
35# DESCRIPTION:
36# With 'compression' set, a file with non-power-of-2 blocksize storage space
37# can be freed as will normally.
38#
39# STRATEGY:
40#	1. Set 'compression' or 'compress' to on or lzjb
41#	2. Set different recordsize with ZFS filesystem
42#	3. Repeatedly using 'randfree_file' to create a file and then free its
43#	   storage space with different range, the system should work normally.
44#
45
46verify_runnable "both"
47
48function cleanup
49{
50	rm -f $TESTDIR/*
51}
52
53function create_free_testing #<file size> <file>
54{
55	typeset -i fsz=$1
56	typeset file=$2
57	typeset -i start=0
58	typeset -i len=0
59	typeset -i dist=0
60
61	for start in 0 `expr $RANDOM % $fsz`
62	do
63		(( dist = fsz - start ))
64		for len in `expr $RANDOM % $dist` $dist \
65			`expr $start + $dist`; do
66			log_must randfree_file -l fsz -s $start \
67				-n $len $file
68			[[ -e $file ]] && \
69				log_must rm -f $file
70		done
71	done
72}
73
74
75log_assert "Creating non-power-of-2 blocksize file and freeing the file \
76	storage space at will should work normally with compression setting"
77log_onexit cleanup
78
79fs=$TESTPOOL/$TESTFS
80single_blk_file=$TESTDIR/singleblkfile.$$
81multi_blk_file=$TESTDIR/multiblkfile.$$
82typeset -i blksize=512
83typeset -i fsize=0
84typeset -i avail=0
85typeset -i blknum=0
86
87for propname in "compression" "compress"
88do
89	for value in $(get_compress_opts zfs_compress)
90	do
91		log_must zfs set compression=$value $fs
92		real_val=$(get_prop $propname $fs)
93		if [[ $value == "gzip-6" ]]; then
94			value="gzip"
95		fi
96                [[ $real_val != $value ]] && \
97                        log_fail "Set property $propname=$value failed."
98
99		(( blksize = 512 ))
100		while (( blksize <= 131072 )); do
101			log_must zfs set recordsize=$blksize $fs
102
103			# doing single block testing
104			(( fsize = $RANDOM ))
105			if (( fsize > blksize )); then
106				(( fsize = fsize % blksize ))
107			fi
108			if (( (fsize % 2) == 0 )); then
109				#make sure fsize is non-power-of-2
110				(( fsize = fsize + 1 ))
111			fi
112			create_free_testing $fsize $single_blk_file
113
114			# doing multiple blocks testing
115			avail=$(get_prop available $fs)
116			(( blknum = avail / blksize ))
117			# we just test <10 multi-blocks to limit testing time
118			(( blknum = blknum % 9 ))
119			while (( blknum < 2 )); do
120				(( blknum = blknum + $RANDOM % 9 ))
121			done
122			if (( (blknum % 2) == 0 )); then
123				(( blknum = blknum + 1 )) # keep blknum as odd
124			fi
125			(( fsize = blknum * blksize ))
126			create_free_testing $fsize $multi_blk_file
127
128			(( blksize = blksize * 2 ))
129		done
130	done
131done
132
133log_pass "Creating and freeing non-power-of-2 blocksize file work as expected."
134