+test_127() { # bug 15521
+ $LSTRIPE -i 0 -c 1 $DIR/$tfile
+ $LCTL set_param osc.*.stats=0
+ FSIZE=$((2048 * 1024))
+ dd if=/dev/zero of=$DIR/$tfile bs=$FSIZE count=1
+ cancel_lru_locks osc
+ dd if=$DIR/$tfile of=/dev/null bs=$FSIZE
+
+ $LCTL get_param osc.*0000-osc-*.stats | grep samples > $DIR/${tfile}.tmp
+ while read NAME COUNT SAMP UNIT MIN MAX SUM SUMSQ; do
+ eval $NAME=$COUNT
+ echo "got $COUNT $NAME"
+
+ case $NAME in
+ read_bytes|write_bytes)
+ [ $MIN -lt 4096 ] && error "min is too small: $MIN"
+ [ $MIN -gt $FSIZE ] && error "min is too big: $MIN"
+ [ $MAX -lt 4096 ] && error "max is too small: $MAX"
+ [ $MAX -gt $FSIZE ] && error "max is too big: $MAX"
+ [ $SUM -ne $FSIZE ] && error "sum is wrong: $SUM"
+ [ $SUMSQ -lt $(((FSIZE /4096) * (4096 * 4096))) ] &&
+ error "sumsquare is too small: $SUMSQ"
+ [ $SUMSQ -gt $((FSIZE * FSIZE)) ] &&
+ error "sumsquare is too big: $SUMSQ"
+ ;;
+ *) ;;
+ esac
+ done < $DIR/${tfile}.tmp
+
+ #check that we actually got some stats
+ [ "$read_bytes" ] || error "no read done"
+ [ "$write_bytes" ] || error "no write done"
+}
+run_test 127 "verify the client stats are sane"
+
+test_128() { # bug 15212
+ touch $DIR/$tfile
+ $LFS 2>&1 <<-EOF | tee $TMP/$tfile.log
+ find $DIR/$tfile
+ find $DIR/$tfile
+ EOF
+
+ result=$(grep error $TMP/$tfile.log)
+ rm -f $DIR/$tfile
+ [ -z "$result" ] || error "consecutive find's under interactive lfs failed"
+}
+run_test 128 "interactive lfs for 2 consecutive find's"
+
+test_129() {
+ [ "$FSTYPE" != "ldiskfs" ] && skip "not needed for FSTYPE=$FSTYPE" && return 0
+
+ DEV=$(basename $(do_facet mds lctl get_param -n osd.*MDT*.mntdev))
+ [ -z "$DEV" ] && error "can't access mds mntdev"
+ EFBIG=27
+ LDPROC=/proc/fs/ldiskfs/$DEV/max_dir_size
+ MAX=16384
+
+ do_facet mds "echo $MAX > $LDPROC"
+
+ mkdir -p $DIR/$tdir
+
+ I=0
+ J=0
+ while [ ! $I -gt $MAX ]; do
+ multiop $DIR/$tdir/$J Oc
+ rc=$?
+ if [ $rc -eq $EFBIG ]; then
+ do_facet mds "echo 0 >$LDPROC"
+ echo "return code $rc received as expected"
+ return 0
+ elif [ $rc -ne 0 ]; then
+ do_facet mds "echo 0 >$LDPROC"
+ error_exit "return code $rc received instead of expected $EFBIG"
+ fi
+ J=$((J+1))
+ I=$(stat -c%s "$DIR/$tdir")
+ done
+
+ error "exceeded dir size limit: $I bytes"
+ do_facet mds "echo 0 >$LDPROC"
+}
+run_test 129 "test directory size limit ========================"
+
+
+test_130a() {
+ filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
+ [ -n "$filefrag_op" ] && skip "filefrag does not support FIEMAP" && return
+
+ local fm_file=$DIR/$tfile
+ lfs setstripe -s 65536 -c 1 $fm_file || error "setstripe failed on $fm_file"
+ dd if=/dev/zero of=$fm_file bs=65536 count=1 || error "dd failed for $fm_file"
+
+ filefrag -ves $fm_file || error "filefrag $fm_file failed"
+ filefrag_op=`filefrag -ve $fm_file | grep -A 100 "ext:" | grep -v "ext:" | grep -v "found"`
+
+ lun=`$GETSTRIPE $fm_file | grep -A 10 obdidx | awk '{print $1}' | grep -v "obdidx"`
+
+ start_blk=`echo $filefrag_op | cut -d: -f2 | cut -d. -f1`
+ IFS=$'\n'
+ tot_len=0
+ for line in $filefrag_op
+ do
+ frag_lun=`echo $line | cut -d: -f5`
+ ext_len=`echo $line | cut -d: -f4`
+ if (( $frag_lun != $lun )); then
+ error "FIEMAP on 1-stripe file($fm_file) failed"
+ return
+ fi
+ (( tot_len += ext_len ))
+ done
+
+ if (( lun != frag_lun || start_blk != 0 || tot_len != 64 )); then
+ error "FIEMAP on 1-stripe file($fm_file) failed;"
+ return
+ fi
+ echo "FIEMAP on single striped file succeeded"
+}
+run_test 130a "FIEMAP (1-stripe file)"
+
+test_130b() {
+ [ "$OSTCOUNT" -lt "2" ] && skip "skipping FIEMAP on 2-stripe file test" && return
+
+ filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
+ [ -n "$filefrag_op" ] && skip "filefrag does not support FIEMAP" && return
+
+ local fm_file=$DIR/$tfile
+ lfs setstripe -s 65536 -c 2 $fm_file || error "setstripe failed on $fm_file"
+ dd if=/dev/zero of=$fm_file bs=1M count=2 || error "dd failed on $fm_file"
+
+ filefrag -ves $fm_file || error "filefrag $fm_file failed"
+ filefrag_op=`filefrag -ve $fm_file | grep -A 100 "ext:" | grep -v "ext:" | grep -v "found"`
+
+ last_lun=`echo $filefrag_op | cut -d: -f5`
+
+ IFS=$'\n'
+ tot_len=0
+ num_luns=1
+ for line in $filefrag_op
+ do
+ frag_lun=`echo $line | cut -d: -f5`
+ ext_len=`echo $line | cut -d: -f4`
+ if (( $frag_lun != $last_lun )); then
+ if (( tot_len != 1024 )); then
+ error "FIEMAP on $fm_file failed; returned len $tot_len for OST $last_lun instead of 256"
+ return
+ else
+ (( num_luns += 1 ))
+ tot_len=0
+ fi
+ fi
+ (( tot_len += ext_len ))
+ last_lun=$frag_lun
+ done
+ if (( num_luns != 2 || tot_len != 1024 )); then
+ error "FIEMAP on $fm_file failed; returned wrong number of luns or wrong len for OST $last_lun"
+ return
+ fi
+
+ echo "FIEMAP on 2-stripe file succeeded"
+}
+run_test 130b "FIEMAP (2-stripe file)"
+
+test_130c() {
+ [ "$OSTCOUNT" -lt "2" ] && skip "skipping FIEMAP on 2-stripe file with hole test" && return
+
+ filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
+ [ -n "$filefrag_op" ] && skip "filefrag does not support FIEMAP" && return
+
+ local fm_file=$DIR/$tfile
+ lfs setstripe -s 65536 -c 2 $fm_file || error "setstripe failed on $fm_file"
+ dd if=/dev/zero of=$fm_file seek=1 bs=1M count=1 || error "dd failed on $fm_file"
+
+ filefrag -ves $fm_file || error "filefrag $fm_file failed"
+ filefrag_op=`filefrag -ve $fm_file | grep -A 100 "ext:" | grep -v "ext:" | grep -v "found"`
+
+ last_lun=`echo $filefrag_op | cut -d: -f5`
+
+ IFS=$'\n'
+ tot_len=0
+ num_luns=1
+ for line in $filefrag_op
+ do
+ frag_lun=`echo $line | cut -d: -f5`
+ ext_len=`echo $line | cut -d: -f4`
+ if (( $frag_lun != $last_lun )); then
+ logical=`echo $line | cut -d: -f2 | cut -d. -f1`
+ if (( logical != 512 )); then
+ error "FIEMAP on $fm_file failed; returned logical start for lun $logical instead of 512"
+ return
+ fi
+ if (( tot_len != 512 )); then
+ error "FIEMAP on $fm_file failed; returned len $tot_len for OST $last_lun instead of 1024"
+ return
+ else
+ (( num_luns += 1 ))
+ tot_len=0
+ fi
+ fi
+ (( tot_len += ext_len ))
+ last_lun=$frag_lun
+ done
+ if (( num_luns != 2 || tot_len != 512 )); then
+ error "FIEMAP on $fm_file failed; returned wrong number of luns or wrong len for OST $last_lun"
+ return
+ fi
+
+ echo "FIEMAP on 2-stripe file with hole succeeded"
+}
+run_test 130c "FIEMAP (2-stripe file with hole)"
+
+test_130d() {
+ [ "$OSTCOUNT" -lt "3" ] && skip "skipping FIEMAP on N-stripe file test" && return
+
+ filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
+ [ -n "$filefrag_op" ] && skip "filefrag does not support FIEMAP" && return
+
+ local fm_file=$DIR/$tfile
+ lfs setstripe -s 65536 -c $OSTCOUNT $fm_file || error "setstripe failed on $fm_file"
+ dd if=/dev/zero of=$fm_file bs=1M count=$OSTCOUNT || error "dd failed on $fm_file"
+
+ filefrag -ves $fm_file || error "filefrag $fm_file failed"
+ filefrag_op=`filefrag -ve $fm_file | grep -A 100 "ext:" | grep -v "ext:" | grep -v "found"`
+
+ last_lun=`echo $filefrag_op | cut -d: -f5`
+
+ IFS=$'\n'
+ tot_len=0
+ num_luns=1
+ for line in $filefrag_op
+ do
+ frag_lun=`echo $line | cut -d: -f5`
+ ext_len=`echo $line | cut -d: -f4`
+ if (( $frag_lun != $last_lun )); then
+ if (( tot_len != 1024 )); then
+ error "FIEMAP on $fm_file failed; returned len $tot_len for OST $last_lun instead of 1024"
+ return
+ else
+ (( num_luns += 1 ))
+ tot_len=0
+ fi
+ fi
+ (( tot_len += ext_len ))
+ last_lun=$frag_lun
+ done
+ if (( num_luns != OSTCOUNT || tot_len != 1024 )); then
+ error "FIEMAP on $fm_file failed; returned wrong number of luns or wrong len for OST $last_lun"
+ return
+ fi
+
+ echo "FIEMAP on N-stripe file succeeded"
+}
+run_test 130d "FIEMAP (N-stripe file)"
+
+test_130e() {
+ [ "$OSTCOUNT" -lt "2" ] && skip "skipping continuation FIEMAP test" && return
+
+ filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
+ [ -n "$filefrag_op" ] && skip "filefrag does not support FIEMAP" && return
+
+ local fm_file=$DIR/$tfile
+ lfs setstripe -s 65536 -c 2 $fm_file || error "setstripe failed on $fm_file"
+ NUM_BLKS=512
+ EXPECTED_LEN=$(( (NUM_BLKS / 2) * 4 ))
+ for ((i = 0; i < $NUM_BLKS; i++))
+ do
+ dd if=/dev/zero of=$fm_file count=1 bs=4096 seek=$((2*$i)) conv=notrunc > /dev/null 2>&1
+ done
+
+ filefrag -ves $fm_file || error "filefrag $fm_file failed"
+ filefrag_op=`filefrag -ve $fm_file | grep -A 750 "ext:" | grep -v "ext:" | grep -v "found"`
+
+ last_lun=`echo $filefrag_op | cut -d: -f5`
+
+ IFS=$'\n'
+ tot_len=0
+ num_luns=1
+ for line in $filefrag_op
+ do
+ frag_lun=`echo $line | cut -d: -f5`
+ ext_len=`echo $line | cut -d: -f4`
+ if (( $frag_lun != $last_lun )); then
+ if (( tot_len != $EXPECTED_LEN )); then
+ error "FIEMAP on $fm_file failed; returned len $tot_len for OST $last_lun instead of $EXPECTED_LEN"
+ return
+ else
+ (( num_luns += 1 ))
+ tot_len=0
+ fi
+ fi
+ (( tot_len += ext_len ))
+ last_lun=$frag_lun
+ done
+ if (( num_luns != 2 || tot_len != $EXPECTED_LEN )); then
+ echo "$num_luns $tot_len"
+ error "FIEMAP on $fm_file failed; returned wrong number of luns or wrong len for OST $last_lun"
+ return
+ fi
+
+ echo "FIEMAP with continuation calls succeeded"
+}
+run_test 130e "FIEMAP (test continuation FIEMAP calls)"
+
+POOL=${POOL:-cea1}
+TGT_COUNT=$OSTCOUNT
+TGTPOOL_FIRST=1
+TGTPOOL_MAX=$(($TGT_COUNT - 1))
+TGTPOOL_STEP=2
+TGTPOOL_LIST=`seq $TGTPOOL_FIRST $TGTPOOL_STEP $TGTPOOL_MAX`
+POOL_ROOT=${POOL_ROOT:-$DIR/d200.pools}
+POOL_DIR=$POOL_ROOT/dir_tst
+POOL_FILE=$POOL_ROOT/file_tst
+
+check_file_in_pool()
+{
+ file=$1
+ res=$($GETSTRIPE $file | grep 0x | cut -f2)
+ for i in $res
+ do
+ found=$(echo :$TGTPOOL_LIST: | tr " " ":" | grep :$i:)
+ if [[ "$found" == "" ]]
+ then
+ echo "pool list: $TGTPOOL_LIST"
+ echo "striping: $res"
+ error "$file not allocated in $POOL"
+ return 1
+ fi
+ done
+ return 0
+}
+
+test_200() {
+ do_facet mgs $LCTL pool_new $FSNAME.$POOL
+ do_facet mgs $LCTL get_param -n lov.$FSNAME-MDT0000-mdtlov.pools.$POOL
+ [ $? == 0 ] || error "Pool creation of $POOL failed"
+}
+run_test 200 "Create new pool =========================================="
+
+test_201() {
+ TGT=$(seq -f $FSNAME-OST%04g_UUID $TGTPOOL_FIRST $TGTPOOL_STEP \
+ $TGTPOOL_MAX | tr '\n' ' ')
+ do_facet mgs $LCTL pool_add $FSNAME.$POOL \
+ $FSNAME-OST[$TGTPOOL_FIRST-$TGTPOOL_MAX/$TGTPOOL_STEP]_UUID
+ res=$(do_facet mgs $LCTL get_param -n lov.$FSNAME-MDT0000-mdtlov.pools.$POOL | sort \
+ | tr '\n' ' ')
+ [ "$res" = "$TGT" ] || error "Pool content ($res) do not match requested ($TGT)"
+}
+run_test 201 "Add targets to a pool ===================================="
+
+test_202a() {
+ mkdir -p $POOL_DIR
+ $SETSTRIPE -c 2 -p $POOL $POOL_DIR
+ [ $? = 0 ] || error "Cannot set pool $POOL to $POOL_DIR"
+}
+run_test 202a "Set pool on a directory ================================="
+
+test_202b() {
+ res=$($GETSTRIPE $POOL_DIR | grep pool: | cut -f8 -d " ")
+ [ "$res" = $POOL ] || error "Pool on $POOL_DIR is not $POOL"
+}
+run_test 202b "Check pool on a directory ==============================="
+
+test_202c() {
+ failed=0
+ for i in $(seq -w 1 $(($TGT_COUNT * 3)))
+ do
+ file=$POOL_DIR/file-$i
+ touch $file
+ check_file_in_pool $file
+ if [[ $? != 0 ]]
+ then
+ failed=$(($failed + 1))
+ fi
+ done
+ [ "$failed" = 0 ] || error "$failed files not allocated in $POOL"
+}
+run_test 202c "Check files allocation from directory pool =============="
+
+test_203() {
+ mkdir -p $POOL_FILE
+ failed=0
+ for i in $(seq -w 1 $(($TGT_COUNT * 3)))
+ do
+ file=$POOL_FILE/spoo-$i
+ $SETSTRIPE -p $POOL $file
+ check_file_in_pool $file
+ if [[ $? != 0 ]]
+ then
+ failed=$(($failed + 1))
+ fi
+ done
+ [ "$failed" = 0 ] || error "$failed files not allocated in $POOL"
+}
+run_test 203 "Create files in a pool ==================================="
+
+test_210a() {
+ TGT=$(do_facet mgs $LCTL get_param -n lov.$FSNAME-MDT0000-mdtlov.pools.$POOL | head -1)
+ do_facet mgs $LCTL pool_remove $FSNAME.$POOL $TGT
+ res=$(do_facet mgs $LCTL get_param -n lov.$FSNAME-MDT0000-mdtlov.pools.$POOL | grep $TGT)
+ [ "$res" = "" ] || error "$TGT not removed from $FSNAME.$POOL"
+}
+run_test 210a "Remove a target from a pool ============================="
+
+test_210b() {
+ for TGT in $(do_facet mgs $LCTL get_param -n lov.$FSNAME-MDT0000-mdtlov.pools.$POOL)
+ do
+ do_facet mgs $LCTL pool_remove $FSNAME.$POOL $TGT
+ done
+ res=$(do_facet mgs $LCTL get_param -n lov.$FSNAME-MDT0000-mdtlov.pools.$POOL)
+ [ "$res" = "" ] || error "Pool $FSNAME.$POOL cannot be drained"
+}
+run_test 210b "Remove all targets from a pool =========================="
+
+test_211() {
+ do_facet mgs $LCTL pool_destroy $FSNAME.$POOL
+ res=$(do_facet mgs "$LCTL get_param -n lov.$FSNAME-MDT0000-mdtlov.pools.$POOL 2>/dev/null")
+ [ "$res" = "" ] || error "Pool $FSNAME.$POOL is not destroyed"
+}
+run_test 211 "Remove a pool ============================================"
+