| #! /bin/bash |
| # FS QA Test 026 |
| # |
| # Test for ea_inode feature in ext4. Without ea_inode feature, an extended |
| # attribute in ext4 cannot be larger than the fs block size. ea_inode feature |
| # allows storing xattr values in external inodes and so raises xattr value |
| # size limit to 64k. |
| # |
| #----------------------------------------------------------------------- |
| # Copyright (c) 2017 Google, Inc. All Rights Reserved. |
| # |
| # This program is free software; you can redistribute it and/or |
| # modify it under the terms of the GNU General Public License as |
| # published by the Free Software Foundation. |
| # |
| # This program is distributed in the hope that it would be useful, |
| # but WITHOUT ANY WARRANTY; without even the implied warranty of |
| # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
| # GNU General Public License for more details. |
| # |
| # You should have received a copy of the GNU General Public License |
| # along with this program; if not, write the Free Software Foundation, |
| # Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA |
| #----------------------------------------------------------------------- |
| # |
| |
| seq=`basename $0` |
| seqres=$RESULT_DIR/$seq |
| echo "QA output created by $seq" |
| |
| tmp=/tmp/$$ |
| status=1 # failure is the default! |
| trap "_cleanup; exit \$status" 0 1 2 3 15 |
| |
| _cleanup() |
| { |
| rm -f $tmp.* |
| } |
| |
| # get standard environment, filters and checks |
| . ./common/rc |
| . ./common/filter |
| . ./common/attr |
| |
| # remove previous $seqres.full before test |
| rm -f $seqres.full |
| |
| # real QA test starts here |
| _supported_fs ext4 |
| _supported_os Linux |
| _require_scratch |
| _require_attrs |
| _require_scratch_ext4_feature "ea_inode" |
| |
| _scratch_mkfs_ext4 -O ea_inode >/dev/null 2>&1 |
| _scratch_mount |
| |
| # Sets an extended attribute on a file. |
| attr_set() |
| { |
| local file=$1 name=$2 value=$3 tmp |
| |
| if [[ "$value" != "" ]]; then |
| $SETFATTR_PROG -n $name -v "$value" $file |
| else |
| $SETFATTR_PROG -n $name $file |
| fi |
| |
| tmp=$($GETFATTR_PROG --absolute-names --only-values -n $name $file) |
| [[ "$tmp" == "$value" ]] || echo "unexpected value returned: $tmp" |
| } |
| |
| # List attributes on a file. |
| attr_list() |
| { |
| $GETFATTR_PROG --absolute-names $1 | grep -v '^#' |
| } |
| |
| # Removes an extended attribute from a file. |
| attr_remove() |
| { |
| local file=$1 name=$2 |
| |
| $SETFATTR_PROG -x $name $file |
| } |
| |
| # Test files. |
| x=$SCRATCH_MNT/x |
| y=$SCRATCH_MNT/y |
| z=$SCRATCH_MNT/z |
| |
| # Attribute with short name that goes into inode body. |
| name_in_ibody=user.i |
| |
| # Attribute with long name that goes into xattr block. |
| name_in_block=user.$(perl -e 'print "b" x 100;') |
| |
| # Set large xattr values on multiple files. |
| touch $x $y $z |
| for file in $x $y $z; do |
| for name in $name_in_ibody $name_in_block; do |
| for size in 4096 8000 $((64*1024)); do |
| attr_set $file $name-$size \ |
| $(perl -e "print 'v' x $size;") |
| done |
| done |
| attr_list $file |
| done |
| rm $x $y $z |
| |
| # Set/remove. |
| touch $x |
| attr_set $x $name_in_ibody $(perl -e "print 'i' x 25000;") |
| attr_set $x $name_in_block $(perl -e "print 'b' x 25000;") |
| attr_list $x |
| attr_remove $x $name_in_ibody |
| attr_remove $x $name_in_block |
| rm $x |
| |
| # Set with same value twice. |
| touch $x |
| attr_set $x $name_in_ibody $(perl -e "print 'i' x 60000;") |
| attr_set $x $name_in_ibody $(perl -e "print 'i' x 60000;") |
| attr_list $x |
| rm $x |
| |
| # Repeatedly set an extended attribute with various value sizes. |
| touch $x |
| for size in 0 10 80 900 1900 3000 9000 60 10000 0 8000 3000 10 0 20 10000 5; do |
| attr_set $x user.1 $(perl -e "print 'v' x $size;") |
| done |
| attr_list $x |
| rm $x |
| |
| # success, all done |
| status=0 |
| exit |