1#!/bin/sh
2# Ensure that du can handle a 2GB file (i.e., a file of size 2^31 bytes)
3# Before coreutils-5.93, on systems with a signed, 32-bit stat.st_blocks
4# one of du's computations would overflow.
5
6# Copyright (C) 2005-2023 Free Software Foundation, Inc.
7
8# This program is free software: you can redistribute it and/or modify
9# it under the terms of the GNU General Public License as published by
10# the Free Software Foundation, either version 3 of the License, or
11# (at your option) any later version.
12
13# This program is distributed in the hope that it will be useful,
14# but WITHOUT ANY WARRANTY; without even the implied warranty of
15# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16# GNU General Public License for more details.
17
18# You should have received a copy of the GNU General Public License
19# along with this program.  If not, see <https://www.gnu.org/licenses/>.
20
21. "${srcdir=.}/tests/init.sh"; path_prepend_ ./src
22print_ver_ du
23
24# Creating a 2GB file counts as 'very expensive'.
25very_expensive_
26
27# Get number of free kilobytes on current partition, so we can
28# skip this test if there is insufficient free space.
29free_kb=$(df -k --output=avail . | tail -n1)
30case "$free_kb" in
31  [0-9]*) ;;
32  *) skip_ "invalid size from df: $free_kb";;
33esac
34
35# Require about 3GB free.
36min_kb=3000000
37test $min_kb -lt $free_kb ||
38{
39  skip_ \
40    "too little free space on current partition: $free_kb (need $min_kb KB)"
41}
42
43big=big
44
45if ! fallocate -l2G $big; then
46  rm -f $big
47  {
48    is_local_dir_ . || skip_ 'Not writing 2GB data to remote'
49    for i in $(seq 100); do
50      # Note: 2147483648 == 2^31. Print floor(2^31/100) per iteration.
51      printf %21474836s x || fail=1
52    done
53    # After the final iteration, append the remaining 48 bytes.
54    printf %48s x || fail=1
55  } > $big || fail=1
56fi
57
58# The allocation may be done asynchronously (BTRFS for example)
59sync $big || framework_failure_
60
61du -k $big > out1 || fail=1
62rm -f $big
63sed 's/^2[0-9][0-9][0-9][0-9][0-9][0-9]	'$big'$/~2M/' out1 > out
64
65cat <<\EOF > exp || framework_failure_
66~2M
67EOF
68
69compare exp out || fail=1
70
71Exit $fail
72