From: Dave Chinner <david@fromorbit.com>
To: Brian Foster <bfoster@redhat.com>
Cc: fstests@vger.kernel.org, xfs@oss.sgi.com
Subject: Re: [PATCH] xfstests/xfs: test inode allocation with fragmented free space
Date: Thu, 4 Jun 2015 08:32:04 +1000 [thread overview]
Message-ID: <20150603223204.GF9143@dastard> (raw)
In-Reply-To: <1433358506-27002-1-git-send-email-bfoster@redhat.com>
On Wed, Jun 03, 2015 at 03:08:26PM -0400, Brian Foster wrote:
> XFS dynamic inode allocation has a fundamental limitation in that an
> inode chunk requires a contiguous extent of a minimum size. Depending on
> the level of free space fragmentation, inode allocation can fail with
> ENOSPC where the filesystem might not be near 100% usage.
>
> The sparse inodes feature was implemented to provide an inode allocation
> strategy that maximizes the ability to allocate inodes under free space
> fragmentation. This test fragments free space and verifies that
> filesystems that support sparse inode allocation can allocate a minimum
> percentage of inodes on the fs.
>
> Signed-off-by: Brian Foster <bfoster@redhat.com>
> ---
>
> This is a test I've been using to verify the effectiveness of the XFS
> sparse inodes feature. I put some effort into trying to make it generic
> and have kind of gone back and forth on the matter. That said, it's kind
> of pointless on ext4, doesn't work well on btrfs because it doesn't
> track inode counts, and is generally expected to fail on XFS filesystems
> without sparse inodes support.
>
> Given all of that, I kind of went in the other direction and let it run
> only for XFS when sparse inodes is supported. We still have broader
> functional sparse inodes testability by virtue of DEBUG, of course.
> Thoughts?
I think it's fine as an xfs specific test given the nature of what
it is testing....
> +
> +_avail_bytes()
> +{
> + avail_kb=`$DF_PROG $SCRATCH_MNT | tail -n1 | awk '{ print $5 }'`
> + echo $((avail_kb * 1024))
DF_PROG --output=avail ?
And maybe should go into common/rc as _get_available_space, along
with the _get_*_inode functions?
> +
> +_consume_freesp()
> +{
> + file=$1
> +
> + # consume nearly all available space (leave ~1MB)
> + avail=`_avail_bytes`
> + filesizemb=$((avail / 1024 / 1024 - 1))
> + $XFS_IO_PROG -fc "falloc 0 ${filesizemb}m" $file \
> + 2>> $seqres.full || _fail "falloc failed"
> +}
Don't use _fail here - just have xfs_io output the error message
and let the golden image catch it. It's only a small filesystem,
if it fails it won't blow the runtime out badly, and we'll still get
sparse inode test coverage...
> +# Allocate inodes in a directory until failure.
> +_alloc_inodes()
> +{
> + dir=$1
> +
> + i=0
> + while [ true ]; do
> + touch $dir/$i 2>> $seqres.full || break
> + i=$((i + 1))
> + done
> +}
> +
> +# real QA test starts here
> +_supported_os Linux
> +
> +_require_scratch
> +_require_xfs_io_command "falloc"
> +_require_xfs_io_command "fpunch"
> +
> +rm -f $seqres.full
> +
> +echo "Silence is golden."
> +
> +_scratch_mkfs_sized $((1024*1024*50)) | _filter_mkfs > /dev/null 2> $tmp.mkfs ||
> + _fail "mkfs failed"
> +. $tmp.mkfs # for isize
That should pass "-i sparse" to _scratch_mkfs_sized, after....
> +
> +# This test runs a workload that is known to fail on XFS unless the sparse
> +# inodes chunk feature is enabled. Skip the test if it is not supported to avoid
> +# unnecessary and expected test failures.
> +$XFS_DB_PROG -c version $SCRATCH_DEV | grep SPARSE_INODES > /dev/null ||
> + _notrun "requires sparse inodes support"
... calling this:
_require_xfs_sparse_inodes()
{
_scratch_mkfs_xfs_supported -m crc=1 -i sparse > /dev/null 2>&1 \
|| _notrun "mkfs.xfs does not support sparse inodes"
_scratch_mkfs_xfs -m crc=1 -i sparse > /dev/null 2>&1
_scratch_mount >/dev/null 2>&1 \
|| _notrun "kernel does not support sparse inodes"
umount $SCRATCH_MOUNT
}
> +
> +_scratch_mount
> +
> +# magic heuristic value of 64 - # of inodes in an XFS inode record
> +FRAG_FACTOR=$((isize * 64))
> +[ $FRAG_FACTOR != 0 ] || _fail "could not calculate fragmentation factor"
Why would isize be zero? And what does this magic hueristic do?
> +_consume_freesp $SCRATCH_MNT/spc
> +
> +offset=`stat -c "%s" $SCRATCH_MNT/spc`
> +offset=$((offset - $FRAG_FACTOR * 2))
I dislike having to look up man pages to understand what code does.
It is grabbing the file size, and stepping back a magic number from
the EOF. I think it is punching inode chunk size holes in the file,
but I could be mistaken...
> +while [ $offset -ge 0 ]; do
> + # punch small holes in the file to fragment free space
> + $XFS_IO_PROG -c "fpunch $offset $FRAG_FACTOR" $SCRATCH_MNT/spc \
> + 2>> $seqres.full || _fail "fpunch failed"
> +
> + # allocate as many inodes as possible
> + mkdir -p $SCRATCH_MNT/offset.$offset > /dev/null 2>&1
> + _alloc_inodes $SCRATCH_MNT/offset.$offset
> +
> + offset=$((offset - $FRAG_FACTOR * 2))
> +done
> +
> +# check the inode % usage
> +iusepct=`$DF_PROG -i $SCRATCH_MNT | tail -n 1 | awk '{ print $6 }' |
> + sed -e 's/%//'`
_get_inode_used_percent()
{
$DF_PROG --output=ipcent $SCRATCH_MNT | tail -1 | sed -e 's/%//'
}
> +if [ $iusepct -lt 95 ]; then
if [ ! _within_tolerance .... ]
> + $DF_PROG -i $SCRATCH_MNT
> + _fail "could not allocate enough inodes"
> +fi
> +
> +_scratch_unmount
No need to unmount scratch here.
Cheers,
Dave.
--
Dave Chinner
david@fromorbit.com
_______________________________________________
xfs mailing list
xfs@oss.sgi.com
http://oss.sgi.com/mailman/listinfo/xfs
next prev parent reply other threads:[~2015-06-03 22:33 UTC|newest]
Thread overview: 3+ messages / expand[flat|nested] mbox.gz Atom feed top
2015-06-03 19:08 [PATCH] xfstests/xfs: test inode allocation with fragmented free space Brian Foster
2015-06-03 22:32 ` Dave Chinner [this message]
2015-06-04 15:53 ` Brian Foster
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20150603223204.GF9143@dastard \
--to=david@fromorbit.com \
--cc=bfoster@redhat.com \
--cc=fstests@vger.kernel.org \
--cc=xfs@oss.sgi.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox