#! /bin/bash
# SPDX-License-Identifier: GPL-2.0
# Copyright (c) 2019 Facebook.  All Rights Reserved.
#
# FS QA Test 590
#
# Tests writing into big fallocates.
#
# Based on an XFS RT subvolume specific test now split into xfs/650.
#
. ./common/preamble
_begin_fstest auto prealloc preallocrw

. ./common/filter

_require_xfs_io_command "falloc"

maxextlen=$((0x1fffff))
bs=4096
rextsize=4
filesz=$(((maxextlen + 1) * bs))

_scratch_mkfs >>$seqres.full 2>&1
_scratch_mount
_require_fs_space "$SCRATCH_MNT" $((filesz / 1024))

# Allocate maxextlen + 1 blocks. As long as the allocator does something sane,
# we should end up with two extents that look something like:
#
# u3.bmx[0-1] = [startoff,startblock,blockcount,extentflag]
# 0:[0,0,2097148,1]
# 1:[2097148,2097148,4,1]
#
# Extent 0 has blockcount = ALIGN_DOWN(maxextlen, rextsize). Extent 1 is
# adjacent and has blockcount = rextsize. Both are unwritten.
$XFS_IO_PROG -c "falloc 0 $filesz" -c fsync -f "$SCRATCH_MNT/file"

# Write extent 0 + one block of extent 1. Our extents should end up like so:
#
# u3.bmx[0-1] = [startoff,startblock,blockcount,extentflag]
# 0:[0,0,2097149,0]
# 1:[2097149,2097149,3,1]
#
# Extent 0 is written and has blockcount = ALIGN_DOWN(maxextlen, rextsize) + 1,
# Extent 1 is adjacent, unwritten, and has blockcount = rextsize - 1 and
# startblock % rextsize = 1.
#
# The -b is just to speed things up (doing GBs of I/O in 4k chunks kind of
# sucks).
$XFS_IO_PROG -c "pwrite -b 1M -W 0 $(((maxextlen + 2 - rextsize) * bs))" \
	"$SCRATCH_MNT/file" >> "$seqres.full"

# Truncate the extents.
$XFS_IO_PROG -c "truncate 0" -c fsync "$SCRATCH_MNT/file"

_scratch_unmount
_check_scratch_fs

echo "Silence is golden"
status=0
exit
