[Ocfs2-devel] [PATCH] ocfs2: Fix wrong search logic in __ocfs2_resv_find_window

Heming Zhao heming.zhao at suse.com
Fri Apr 21 08:43:13 UTC 2023


On Fri, Apr 21, 2023 at 04:01:29PM +0800, Heming Zhao via Ocfs2-devel wrote:
> On Fri, Apr 21, 2023 at 03:35:01PM +0800, Joseph Qi wrote:
> > Hi,
> > Could you please share a reproducer?
> > 
> 
> Anyone could access & download the URL [1] (I wrote it in patch commit log)
> without register SUSE account.
> 
> Please check attachment file, which I downloaded from [1] and modified under
> the BZ comment 1. The trigger method is also in comment 1, I copy here:
> ./defragfs_test.sh -d /dev/vdf -m /mnt -n ocfstst -s pcmk -o /tmp -b 1024 -c 8192
> 
> note: you may modify '-n' (cluster name) & -s' (cluster stack).
> 
> [1]: https://bugzilla.suse.com/show_bug.cgi?id=1131931
> 

It looks the attachment file was removed by oracle mail server.
I copy & past it here:

```
#!/bin/sh
#
# mkfs_test -o <outdir> -d <device> -b <blocksize> -c <clustersize>
#
usage() {
    echo "usage: ${DEFRAGFS_TEST} -o <outdir> -d <device> -m <mountpoint> -b <blocksize> -c <clustersize> -s <cluster-stack> -n <cluster-name>"
    echo "       -o output directory for the logs"
    echo "       -d device"
    echo "       -m mountpoint"
    echo "       -b blocksize"
    echo "       -c clustersize"
    echo "       -s cluster stack"
    echo "       -n cluster name"
    exit 1
}

get_partsz() {
	if [ -h "${device}" ]; then
		device=`readlink -f "${device}"`
	fi

    dev=`echo ${device} | sed 's/\/dev\///'`
    num=`cat /proc/partitions | ${AWK} -v DEV=${dev} '
		BEGIN{dev=DEV} // {split($0, a); if (a[4] == dev) {printf("%u\n", $3); exit 0;} }'`
    if [ ${num} -eq 0 ]; then
        echo "error: unable to find size of device"  |tee -a ${LOGFILE}
        exit 1
    fi

    partsz=$[${num}*1024]
    return 0
}

do_fsck() {
    if [ "$#" -lt "1" ]; then
        echo "do_fsck(): <out>" |tee -a ${LOGFILE}
        exit 1
    fi
    out=$1
    echo ${FSCK} -fn ${device} >>${LOGFILE}
    echo -n "fsck ..... " |tee -a ${LOGFILE}
    echo ${FSCK} -fn ${device} >>${out}
    ${FSCK} -fn ${device} >>${out} 2>&1
    grep "All passes succeeded" ${LOGFILE} >/dev/null 2>&1
    grep "All passes succeeded" ${out} >/dev/null 2>&1
    if [ $? -ne 0 ] ; then
        echo "FAILED. Errors in ${out}" |tee -a ${LOGFILE}
        exit 1
    else
        echo "OK" |tee -a ${LOGFILE}
    fi
    echo "" >> ${out}
    return 0
}

do_mkfs() {
    if [ "$#" -lt "6" ] ; then
        echo "do_mkfs(): blocksize clustersize device volsize out cluster-stack cluster-name"  |tee -a ${LOGFILE}
        exit 1
    fi

    B=$1
    C=$2
    D=$3
    #V=$4
    O=$4
    S=$5
    N=$6

    echo ${MKFS} -b ${B} -C ${C} ${D} --cluster-stack=${S} --cluster-name=${N} >> ${LOGFILE}
    echo -n "mkfs ..... " |tee -a ${LOGFILE}
    echo ${MKFS} -b ${B} -C ${C} ${D} --cluster-stack=${S} --cluster-name=${N} >> ${O}
    ${MKFS} -x -F -b ${B} -C ${C} -N 1 -J size=4M ${D} --cluster-stack=${S} $numblks --cluster-name=${N} >> ${O} 2>&1
    echo "OK" |tee -a ${LOGFILE}
    echo "" >> ${O}
}

do_mount() {
	# mount the device on mntdir
	echo -n "mount ${device} ${mntdir} " |tee -a ${LOGFILE}
	${MOUNT} -t ocfs2 ${device} ${mntdir} 2>/dev/null
	if [ $? -ne 0 ]
	then
		echo -n "FAILED. Check dmesg for errors." 2>&1  |tee -a ${LOGFILE}
		exit 1
	else
		echo "OK"  |tee -a ${LOGFILE}
	fi
}


do_defragfs() {
	$DEFRAGFS $mntdir
}

do_genfrag_old() {
	# 应该使用一个新的方法来产生空洞文件,类似lseek的方法,但是仔细想过以后,发现lseek好像并不适用
	# 另一种方法就是直接切断inode的部分索引
    	if [ "$#" -lt "1" ] ; then
        	echo "do_genfrag(): blocksize"  |tee -a ${LOGFILE}
        	exit 1
    	fi
	in_dev="/dev/random"
	blk_sz=$1
        max_num=$[$partsz/($blk_sz*5000)]
        if [ "$max_num" -gt "100" ]
	then
		max_num=1
	fi
	for i in `seq 1 $max_num`
	do
		tmp_file=${mntdir%*/}/test_from_dd$i
		dd if=/dev/urandom of=$tmp_file bs=$blk_sz count=5000
		echo "dd if=/dev/urandom of=$tmp_file bs=$blk_sz count=5000"
		cd $mntdir
		split -b $blk_sz $tmp_file "zheshishenmedongxi"
		# exit 1
		rm -rf zheshishenmedongxi*x
		rm -rf $tmp_file
		cat zheshishenmedongxi* > $tmp_file 
		rm -rf zheshishenmedongxi*
		md5sum $tmp_file > $tmp_file"_md5"
		cd -
	done
	#echo "exit..."
	#exit 100
}

do_genfrag() {
    	if [ "$#" -lt "1" ] ; then
        	echo "do_genfrag(): blocksize"  |tee -a ${LOGFILE}
        	exit 1
    	fi
	in_dev="/dev/random"
	cluster_sz=$1
        max_num=$[$partsz/($cluster_sz*100)]
        if [ "$max_num" -gt "100" ]
	then
		max_num=100
	fi
	cd $mntdir
	for i in `seq 1 100` 
	do
		for j in `seq 1 $max_num`
		do
			tmp_file=${mntdir%*/}/test_from_dd$j
			dd if=/dev/urandom of=tmp_file bs=$cluster_sz count=1 > /dev/null 2>&1
			echo "dd if=/dev/urandom of=tmp_file bs=$cluster_sz count=1"
			cat tmp_file >> $tmp_file 
		done
	done
	for i in `seq 1 $max_num`
	do
		tmp_file=${mntdir%*/}/test_from_dd$i
		md5sum $tmp_file > $tmp_file"_md5"
	done
	cd -
	#echo "exit..."
	#exit 100
}

check_md5() {
	cd $mntdir
	md5sum --check *_md5
	cd -
	if [ $? -ne 0 ] 
        then
                echo "FAILED. after defragfs, the file md5 code not match." 2>&1  |tee -a ${LOGFILE}
                exit 1
        else
                echo "md5 check OK"  |tee -a ${LOGFILE}
        fi

}

do_umount() {
	# umount the volume
	echo -n "umount ${mntdir} "  |tee -a ${LOGFILE}
	${UMOUNT} ${mntdir} 2>/dev/null
	if [ $? -ne 0 ]
	then
		echo "FAILED. Check dmesg for errors." 2>&1  |tee -a ${LOGFILE}
		exit 1
	else
		echo "OK"  |tee -a ${LOGFILE}
	fi
}


DEFRAGFS="`which sudo` -u root `which defragfs.ocfs2`"
MKFS="`which sudo` -u root `which mkfs.ocfs2`"
FSCK="`which sudo` -u root `which fsck.ocfs2`"
DEBUGFS="`which sudo` -u root `which debugfs.ocfs2`"
MOUNT="`which sudo` -u root `which mount.ocfs2`"
UMOUNT="`which sudo` -u root `which umount`"
MKDIR="`which sudo` -u root `which mkdir`"
RM="`which sudo` -u root `which rm`"
GREP=`which grep`
DATE=`which date`
AWK=`which awk`
DD=`which dd`

DEFRAGFS_TEST=`basename $0`

bindir=`basename ${0}`
outdir=`basename ${bindir}`
device=
mntdir=
blocksize="NONE"
clustersize="NONE"
OPTIND=1

# TODO: add persent
while getopts "d:i:o:m:c:b:s:n:" args
do
  case "$args" in
    o) outdir="$OPTARG";;
    d) device="$OPTARG";;
    m) mntdir="$OPTARG";;
    b) blocksize="$OPTARG";;
    c) clustersize="$OPTARG";;
    s) cluster_stack="$OPTARG";;
    n) cluster_name="$OPTARG";;
  esac
done
LOGFILE=${outdir}/defragfs-test.log
if [ -f ${LOGFILE} ]; then
	mv ${LOGFILE} `dirname ${LOGFILE}`/`date +%F-%H-%M-%S`-`basename ${LOGFILE}`
fi;

if [ -z "${outdir}" ]; then
    echo "invalid output directory: ${outdir}"
    usage ;
fi

if [ ! -b "${device}" ]; then
    echo "invalid device: ${device}" #|tee -a ${LOGFILE}
    usage ;
fi

if [ -z "${mntdir}" ]; then
    echo "invalid mount point: ${mntdir}" #|tee -a ${LOGFILE}
    usage ;
fi

if [ -z "${cluster_stack}" ]; then
    echo "invalid cluster stack: ${cluster_stack}" #|tee -a ${LOGFILE}
    usage ;
fi

if [ -z "${cluster_name}" ]; then
    echo "invalid cluster name: ${cluster_name}" #|tee -a ${LOGFILE}
    usage ;
fi

echo "create logdir ${outdir}" #|tee -a ${LOGFILE}
mkdir -p ${outdir}

#get partition size
partsz=0
get_partsz


#numblks=10485760

testnum=1

if [ "$blocksize" != "NONE" ];then
    bslist="$blocksize"
else
    bslist="512 1024 2048 4096"
fi

if [ "$clustersize" != "NONE" ];then
    cslist="$clustersize"
else
    cslist="4096 8192 16384 32768 65536 131072 262144 524288 1048576"
fi

echo $bslist
echo $cslist
### Test all combinations of blocksizes and clustersizes
for blks in $(echo "$bslist")
do
    for clusts in $(echo "$cslist")
    do
        TAG=defragfs_test_${testnum}
        OUT=${outdir}/${TAG}.log
	if [ -f ${OUT} ]; then
		rm -f ${OUT};
	fi;

        echo "Test ${testnum}: -b ${blks} -C ${clusts}" #|tee -a ${LOGFILE}
        do_mkfs ${blks} ${clusts} ${device} ${OUT} ${cluster_stack} ${cluster_name}
        do_fsck ${OUT}
	do_mount
	do_genfrag ${clusts}
	#exit 100
	do_defragfs
	do_umount
    done
done
exit 0


### Test option '-T mail'
TAG=defragfs_test_${testnum}
OUT=${outdir}/${TAG}.log
if [ -f ${OUT} ]; then
	rm -f ${OUT};
fi;
echo "Test ${testnum}: -T mail" #|tee -a ${LOGFILE}
echo -n "mkfs ..... " #|tee -a ${LOGFILE}
${MKFS} -x -F -b 4K -C 4K -N 2 -T mail ${device} 262144 >${OUT} 2>&1
echo "OK" #|tee -a ${LOGFILE}
echo -n "verify ..... " #|tee -a ${LOGFILE}
${DEBUGFS} -R "ls -l //" ${device} >>${OUT} 2>&1
num=`${AWK} '/journal:0000/ {print $6;}' ${OUT}`
if [ $num -ne 134217728 ]; then
    echo "ERROR: Journal size too small for type mail" >> ${OUT}
    echo "" >> ${OUT}
    echo "FAILED. Errors in ${OUT}" #|tee -a ${LOGFILE}
else
    echo "OK" #|tee -a ${LOGFILE}
fi
do_fsck ${OUT}
```

Thanks



More information about the Ocfs2-devel mailing list