[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <20150815015207.4333.10934.stgit@birch.djwong.org>
Date: Fri, 14 Aug 2015 18:52:07 -0700
From: "Darrick J. Wong" <darrick.wong@...cle.com>
To: david@...morbit.com, darrick.wong@...cle.com
Cc: linux-ext4@...r.kernel.org, fstests@...r.kernel.org,
xfs@....sgi.com
Subject: [PATCH 1/7] common: add routines to fuzz filesystems
Create common/populate with routines to support the new fuzz tests.
Signed-off-by: Darrick J. Wong <darrick.wong@...cle.com>
---
common/populate | 546 +++++++++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 546 insertions(+)
create mode 100644 common/populate
diff --git a/common/populate b/common/populate
new file mode 100644
index 0000000..d166c24
--- /dev/null
+++ b/common/populate
@@ -0,0 +1,546 @@
+##/bin/bash
+# Routines for populating a scratch fs, and helpers to exercise an FS
+# once it's been fuzzed.
+#-----------------------------------------------------------------------
+# Copyright (c) 2015 Oracle. 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; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will 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 to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+# USA
+#
+# Contact information: Silicon Graphics, Inc., 1500 Crittenden Lane,
+# Mountain View, CA 94043, USA, or: http://www.sgi.com
+#-----------------------------------------------------------------------
+
+_require_xfs_io_command "falloc"
+_require_xfs_io_command "fpunch"
+
+_require_xfs_db_blocktrash_z_command() {
+ test "${FSTYP}" = "xfs" || _notrun "cannot run xfs_db on ${FSTYP}"
+ $XFS_DB_PROG -x -f -c 'blocktrash -z' "${TEST_DEV}" | grep -q 'nothing on stack' || _notrun "blocktrash -z not supported"
+}
+
+# Attempt to make files of "every" format for data, dirs, attrs etc.
+# (with apologies to Eric Sandeen for mutating xfser.sh)
+
+# Create a large directory
+__populate_create_dir() {
+ name="$1"
+ nr="$2"
+ missing="$3"
+
+ mkdir -p "${name}"
+ seq 0 "${nr}" | while read d; do
+ creat=mkdir
+ test "$((d % 20))" -eq 0 && creat=touch
+ $creat "${name}/$(printf "%.08d" "$d")"
+ done
+
+ test -z "${missing}" && return
+ seq 1 2 "${nr}" | while read d; do
+ rm -rf "${name}/$(printf "%.08d" "$d")"
+ done
+}
+
+# Add a bunch of attrs to a file
+__populate_create_attr() {
+ name="$1"
+ nr="$2"
+ missing="$3"
+
+ touch "${name}"
+ seq 0 "${nr}" | while read d; do
+ setfattr -n "user.$(printf "%.08d" "$d")" -v "$(printf "%.08d" "$d")" "${name}"
+ done
+
+ test -z "${missing}" && return
+ seq 1 2 "${nr}" | while read d; do
+ setfattr -x "user.$(printf "%.08d" "$d")" "${name}"
+ done
+}
+
+# Fill up 60% of the remaining free space
+__populate_fill_fs() {
+ dir="$1"
+ pct="$2"
+ test -z "${pct}" && pct=60
+
+ SRC_SZ="$(du -ks "${SRCDIR}" | cut -f 1)"
+ FS_SZ="$(( $(stat -f "${dir}" -c '%a * %S') / 1024 ))"
+
+ NR="$(( (FS_SZ * ${pct} / 100) / SRC_SZ ))"
+ test "${NR}" -lt 1 && NR=1
+
+ seq 1 "${NR}" | while read nr; do
+ cp -pRdu "${SRCDIR}" "${dir}/test.${nr}" >> $seqres.full 2>&1
+ done
+}
+
+# Populate an XFS on the scratch device with (we hope) all known
+# types of metadata block
+_scratch_xfs_populate() {
+ _scratch_mount
+ blksz="$(stat -f -c '%s' "${SCRATCH_MNT}")"
+ dblksz="$(xfs_info "${SCRATCH_MNT}" | grep naming.*bsize | sed -e 's/^.*bsize=//g' -e 's/\([0-9]*\).*$/\1/g')"
+ leaf_lblk="$((32 * 1073741824 / blksz))"
+ node_lblk="$((64 * 1073741824 / blksz))"
+
+ # Data:
+
+ # Regular files
+ # - FMT_EXTENTS
+ echo "+ extents file"
+ $XFS_IO_PROG -f -c "pwrite -S 0x61 0 ${blksz}" "${SCRATCH_MNT}/S_IFREG.FMT_EXTENTS"
+
+ # - FMT_BTREE
+ echo "+ btree extents file"
+ nr="$((blksz * 2 / 16))"
+ $XFS_IO_PROG -f -c "pwrite -S 0x62 0 $((blksz * nr))" "${SCRATCH_MNT}/S_IFREG.FMT_BTREE"
+ for i in $(seq 1 2 ${nr}); do
+ $XFS_IO_PROG -f -c "fpunch $((i * blksz)) ${blksz}" "${SCRATCH_MNT}/S_IFREG.FMT_BTREE"
+ done
+
+ # Directories
+ # - INLINE
+ echo "+ inline dir"
+ __populate_create_dir "${SCRATCH_MNT}/S_IFDIR.FMT_INLINE" 1
+
+ # - BLOCK
+ echo "+ block dir"
+ __populate_create_dir "${SCRATCH_MNT}/S_IFDIR.FMT_BLOCK" "$((dblksz / 40))"
+
+ # - LEAF
+ echo "+ leaf dir"
+ __populate_create_dir "${SCRATCH_MNT}/S_IFDIR.FMT_LEAF" "$((dblksz / 12))"
+
+ # - NODE
+ echo "+ node dir"
+ __populate_create_dir "${SCRATCH_MNT}/S_IFDIR.FMT_NODE" "$((16 * dblksz / 40))" true
+
+ # - BTREE
+ __populate_create_dir "${SCRATCH_MNT}/S_IFDIR.FMT_BTREE" "$((128 * dblksz / 40))" true
+
+ # Symlinks
+ # - FMT_LOCAL
+ echo "+ inline symlink"
+ ln -s target "${SCRATCH_MNT}/S_IFLNK.FMT_LOCAL"
+
+ # - FMT_EXTENTS
+ echo "+ extents symlink"
+ ln -s "$(perl -e 'print "x" x 1023;')" "${SCRATCH_MNT}/S_IFLNK.FMT_EXTENTS"
+
+ # Char & block
+ echo "+ special"
+ mkdir devices
+ mknod "${SCRATCH_MNT}/S_IFCHR" c 1 1
+ mknod "${SCRATCH_MNT}/S_IFBLK" c 1 1
+
+ # Attribute formats
+ # LOCAL
+ echo "+ local attr"
+ __populate_create_attr "${SCRATCH_MNT}/ATTR.FMT_LOCAL" 1
+
+ # LEAF
+ echo "+ leaf attr"
+ __populate_create_attr "${SCRATCH_MNT}/ATTR.FMT_LEAF" "$((blksz / 40))"
+
+ # NODE
+ echo "+ node attr"
+ __populate_create_attr "${SCRATCH_MNT}/ATTR.FMT_NODE" "$((8 * blksz / 40))"
+
+ # BTREE
+ echo "+ btree attr"
+ __populate_create_attr "${SCRATCH_MNT}/ATTR.FMT_BTREE" "$((64 * blksz / 40))" true
+
+ # FMT_EXTENTS with a remote less-than-a-block value
+ echo "+ attr extents with a remote less-than-a-block value"
+ touch "${SCRATCH_MNT}/ATTR.FMT_EXTENTS_REMOTE3K"
+ $XFS_IO_PROG -f -c "pwrite -S 0x43 0 3k" "${SCRATCH_MNT}/attrvalfile" > /dev/null
+ attr -q -s user.remotebtreeattrname "${SCRATCH_MNT}/ATTR.FMT_EXTENTS_REMOTE3K" < "${SCRATCH_MNT}/attrvalfile"
+
+ # FMT_EXTENTS with a remote block-size value
+ echo "+ attr extents with a remote one-block value"
+ touch "${SCRATCH_MNT}/ATTR.FMT_EXTENTS_REMOTE4K"
+ $XFS_IO_PROG -f -c "pwrite -S 0x44 0 4k" "${SCRATCH_MNT}/attrvalfile" > /dev/null
+ attr -q -s user.remotebtreeattrname "${SCRATCH_MNT}/ATTR.FMT_EXTENTS_REMOTE4K" < "${SCRATCH_MNT}/attrvalfile"
+ rm -rf "${SCRATCH_MNT}/attrvalfile"
+
+ # Make an unused inode
+ echo "+ empty file"
+ touch "${SCRATCH_MNT}/unused"
+ $XFS_IO_PROG -f -c 'fsync' "${SCRATCH_MNT}/unused"
+ rm -rf "${SCRATCH_MNT}/unused"
+
+ # Copy some real files (xfs tests, I guess...)
+ echo "+ real files"
+ #__populate_fill_fs "${SCRATCH_MNT}" 40
+ cp -pRdu --reflink=always "${SCRATCH_MNT}/S_IFREG.FMT_BTREE" "${SCRATCH_MNT}/S_IFREG.FMT_BTREE.REFLINK" 2> /dev/null
+
+ umount "${SCRATCH_MNT}"
+}
+
+# Populate an ext4 on the scratch device with (we hope) all known
+# types of metadata block
+_scratch_ext4_populate() {
+ _scratch_mount
+ blksz="$(stat -f -c '%s' "${SCRATCH_MNT}")"
+ dblksz="${blksz}"
+ leaf_lblk="$((32 * 1073741824 / blksz))"
+ node_lblk="$((64 * 1073741824 / blksz))"
+
+ # Data:
+
+ # Regular files
+ # - FMT_INLINE
+ echo "+ inline file"
+ $XFS_IO_PROG -f -c "pwrite -S 0x61 0 1" "${SCRATCH_MNT}/S_IFREG.FMT_INLINE"
+
+ # - FMT_EXTENTS
+ echo "+ extents file"
+ $XFS_IO_PROG -f -c "pwrite -S 0x61 0 ${blksz}" "${SCRATCH_MNT}/S_IFREG.FMT_EXTENTS"
+
+ # - FMT_ETREE
+ echo "+ extent tree file"
+ nr="$((blksz * 2 / 12))"
+ $XFS_IO_PROG -f -c "pwrite -S 0x62 0 $((blksz * nr))" "${SCRATCH_MNT}/S_IFREG.FMT_ETREE"
+ for i in $(seq 1 2 ${nr}); do
+ $XFS_IO_PROG -f -c "fpunch $((i * blksz)) ${blksz}" "${SCRATCH_MNT}/S_IFREG.FMT_ETREE"
+ done
+
+ # Directories
+ # - INLINE
+ echo "+ inline dir"
+ __populate_create_dir "${SCRATCH_MNT}/S_IFDIR.FMT_INLINE" 1
+
+ # - BLOCK
+ echo "+ block dir"
+ __populate_create_dir "${SCRATCH_MNT}/S_IFDIR.FMT_BLOCK" "$((dblksz / 24))"
+
+ # - HTREE
+ echo "+ htree dir"
+ __populate_create_dir "${SCRATCH_MNT}/S_IFDIR.FMT_HTREE" "$((4 * dblksz / 24))"
+
+ # Symlinks
+ # - FMT_LOCAL
+ echo "+ inline symlink"
+ ln -s target "${SCRATCH_MNT}/S_IFLNK.FMT_LOCAL"
+
+ # - FMT_EXTENTS
+ echo "+ extents symlink"
+ ln -s "$(perl -e 'print "x" x 1023;')" "${SCRATCH_MNT}/S_IFLNK.FMT_EXTENTS"
+
+ # Char & block
+ echo "+ special"
+ mkdir devices
+ mknod "${SCRATCH_MNT}/S_IFCHR" c 1 1
+ mknod "${SCRATCH_MNT}/S_IFBLK" c 1 1
+
+ # Attribute formats
+ # LOCAL
+ echo "+ local attr"
+ __populate_create_attr "${SCRATCH_MNT}/ATTR.FMT_LOCAL" 1
+
+ # BLOCK
+ echo "+ block attr"
+ __populate_create_attr "${SCRATCH_MNT}/ATTR.FMT_BLOCK" "$((blksz / 40))"
+
+ # Make an unused inode
+ echo "+ empty file"
+ touch "${SCRATCH_MNT}/unused"
+ $XFS_IO_PROG -f -c 'fsync' "${SCRATCH_MNT}/unused"
+ rm -rf "${SCRATCH_MNT}/unused"
+
+ # Copy some real files (xfs tests, I guess...)
+ echo "+ real files"
+ __populate_fill_fs "${SCRATCH_MNT}"
+ cp -pRdu --reflink=always "${SCRATCH_MNT}/S_IFREG.FMT_ETREE" "${SCRATCH_MNT}/S_IREG.FMT_ETREE.REFLINK" 2> /dev/null
+
+ umount "${SCRATCH_MNT}"
+}
+
+# Find the inode number of a file
+__populate_find_inode() {
+ name="$1"
+ inode="$(stat -c '%i' "${name}")"
+ echo "${inode}"
+}
+
+# Check data fork format of XFS file
+__populate_check_xfs_dformat() {
+ dev="$1"
+ inode="$2"
+ format="$3"
+
+ fmt="$($XFS_DB_PROG -c "inode ${inode}" -c 'p core.format' "${dev}" | sed -e 's/^.*(\([a-z]*\)).*$/\1/g')"
+ test "${format}" = "${fmt}" || _fail "failed to create ino ${inode} dformat expected ${format} saw ${fmt}"
+}
+
+# Check attr fork format of XFS file
+__populate_check_xfs_aformat() {
+ dev="$1"
+ inode="$2"
+ format="$3"
+
+ fmt="$($XFS_DB_PROG -c "inode ${inode}" -c 'p core.aformat' "${dev}" | sed -e 's/^.*(\([a-z]*\)).*$/\1/g')"
+ test "${format}" = "${fmt}" || _fail "failed to create ino ${inode} aformat expected ${format} saw ${fmt}"
+}
+
+# Check structure of XFS directory
+__populate_check_xfs_dir() {
+ dev="$1"
+ inode="$2"
+ dtype="$3"
+
+ (test -n "${leaf_lblk}" && test -n "${node_lblk}") || _fail "must define leaf_lblk and node_lblk before calling __populate_check_xfs_dir"
+ datab=0
+ leafb=0
+ freeb=0
+ #echo "== check dir ${inode} type ${dtype}" ; $XFS_DB_PROG -x -c "inode ${inode}" -c "bmap" "${SCRATCH_DEV}"
+ $XFS_DB_PROG -x -c "inode ${inode}" -c "dblock 0" -c "stack" "${SCRATCH_DEV}" | grep -q 'file data block is unmapped' || datab=1
+ $XFS_DB_PROG -x -c "inode ${inode}" -c "dblock ${leaf_lblk}" -c "stack" "${SCRATCH_DEV}" | grep -q 'file data block is unmapped' || leafb=1
+ $XFS_DB_PROG -x -c "inode ${inode}" -c "dblock ${node_lblk}" -c "stack" "${SCRATCH_DEV}" | grep -q 'file data block is unmapped' || freeb=1
+
+ case "${dtype}" in
+ "shortform"|"inline"|"local")
+ (test "${datab}" -eq 0 && test "${leafb}" -eq 0 && test "${freeb}" -eq 0) || _fail "failed to create ${dtype} dir ino ${inode} datab ${datab} leafb ${leafb} freeb ${freeb}"
+ ;;
+ "block")
+ (test "${datab}" -eq 1 && test "${leafb}" -eq 0 && test "${freeb}" -eq 0) || _fail "failed to create ${dtype} dir ino ${inode} datab ${datab} leafb ${leafb} freeb ${freeb}"
+ ;;
+ "leaf")
+ (test "${datab}" -eq 1 && test "${leafb}" -eq 1 && test "${freeb}" -eq 0) || _fail "failed to create ${dtype} dir ino ${inode} datab ${datab} leafb ${leafb} freeb ${freeb}"
+ ;;
+ "node"|"btree")
+ (test "${datab}" -eq 1 && test "${leafb}" -eq 1 && test "${freeb}" -eq 1) || _fail "failed to create ${dtype} dir ino ${inode} datab ${datab} leafb ${leafb} freeb ${freeb}"
+ ;;
+ *)
+ _fail "Unknown directory type ${dtype}"
+ esac
+}
+
+# Check structure of XFS attr
+__populate_check_xfs_attr() {
+ dev="$1"
+ inode="$2"
+ atype="$3"
+
+ datab=0
+ leafb=0
+ #echo "== check attr ${inode} type ${dtype}" ; $XFS_DB_PROG -x -c "inode ${inode}" -c "bmap -a" "${SCRATCH_DEV}"
+ $XFS_DB_PROG -x -c "inode ${inode}" -c "ablock 0" -c "stack" "${SCRATCH_DEV}" | grep -q 'file attr block is unmapped' || datab=1
+ $XFS_DB_PROG -x -c "inode ${inode}" -c "ablock 1" -c "stack" "${SCRATCH_DEV}" | grep -q 'file attr block is unmapped' || leafb=1
+
+ case "${atype}" in
+ "shortform"|"inline"|"local")
+ (test "${datab}" -eq 0 && test "${leafb}" -eq 0) || _fail "failed to create ${atype} attr ino ${inode} datab ${datab} leafb ${leafb}"
+ ;;
+ "leaf")
+ (test "${datab}" -eq 1 && test "${leafb}" -eq 0) || _fail "failed to create ${atype} attr ino ${inode} datab ${datab} leafb ${leafb}"
+ ;;
+ "node"|"btree")
+ (test "${datab}" -eq 1 && test "${leafb}" -eq 1) || _fail "failed to create ${atype} attr ino ${inode} datab ${datab} leafb ${leafb}"
+ ;;
+ *)
+ _fail "Unknown attribute type ${atype}"
+ esac
+}
+
+# Check that populate created all the types of files we wanted
+_scratch_xfs_populate_check() {
+ _scratch_mount
+ extents_file="$(__populate_find_inode "${SCRATCH_MNT}/S_IFREG.FMT_EXTENTS")"
+ btree_file="$(__populate_find_inode "${SCRATCH_MNT}/S_IFREG.FMT_BTREE")"
+ inline_dir="$(__populate_find_inode "${SCRATCH_MNT}/S_IFDIR.FMT_INLINE")"
+ block_dir="$(__populate_find_inode "${SCRATCH_MNT}/S_IFDIR.FMT_BLOCK")"
+ leaf_dir="$(__populate_find_inode "${SCRATCH_MNT}/S_IFDIR.FMT_LEAF")"
+ node_dir="$(__populate_find_inode "${SCRATCH_MNT}/S_IFDIR.FMT_NODE")"
+ btree_dir="$(__populate_find_inode "${SCRATCH_MNT}/S_IFDIR.FMT_BTREE")"
+ local_slink="$(__populate_find_inode "${SCRATCH_MNT}/S_IFLNK.FMT_LOCAL")"
+ extents_slink="$(__populate_find_inode "${SCRATCH_MNT}/S_IFLNK.FMT_EXTENTS")"
+ bdev="$(__populate_find_inode "${SCRATCH_MNT}/S_IFBLK")"
+ cdev="$(__populate_find_inode "${SCRATCH_MNT}/S_IFCHR")"
+ local_attr="$(__populate_find_inode "${SCRATCH_MNT}/ATTR.FMT_LOCAL")"
+ leaf_attr="$(__populate_find_inode "${SCRATCH_MNT}/ATTR.FMT_LEAF")"
+ node_attr="$(__populate_find_inode "${SCRATCH_MNT}/ATTR.FMT_NODE")"
+ btree_attr="$(__populate_find_inode "${SCRATCH_MNT}/ATTR.FMT_BTREE")"
+
+ blksz="$(stat -f -c '%s' "${SCRATCH_MNT}")"
+ dblksz="$(xfs_info "${SCRATCH_MNT}" | grep naming.*bsize | sed -e 's/^.*bsize=//g' -e 's/\([0-9]*\).*$/\1/g')"
+ leaf_lblk="$((32 * 1073741824 / blksz))"
+ node_lblk="$((64 * 1073741824 / blksz))"
+ umount "${SCRATCH_MNT}"
+
+ __populate_check_xfs_dformat "${SCRATCH_DEV}" "${extents_file}" "extents"
+ __populate_check_xfs_dformat "${SCRATCH_DEV}" "${btree_file}" "btree"
+ __populate_check_xfs_dir "${SCRATCH_DEV}" "${inline_dir}" "inline"
+ __populate_check_xfs_dir "${SCRATCH_DEV}" "${block_dir}" "block"
+ __populate_check_xfs_dir "${SCRATCH_DEV}" "${leaf_dir}" "leaf"
+ __populate_check_xfs_dir "${SCRATCH_DEV}" "${node_dir}" "node"
+ __populate_check_xfs_dir "${SCRATCH_DEV}" "${btree_dir}" "btree"
+ __populate_check_xfs_dformat "${SCRATCH_DEV}" "${btree_dir}" "btree"
+ __populate_check_xfs_dformat "${SCRATCH_DEV}" "${bdev}" "dev"
+ __populate_check_xfs_dformat "${SCRATCH_DEV}" "${cdev}" "dev"
+ __populate_check_xfs_attr "${SCRATCH_DEV}" "${local_attr}" "local"
+ __populate_check_xfs_attr "${SCRATCH_DEV}" "${leaf_attr}" "leaf"
+ __populate_check_xfs_attr "${SCRATCH_DEV}" "${node_attr}" "node"
+ __populate_check_xfs_attr "${SCRATCH_DEV}" "${btree_attr}" "btree"
+ __populate_check_xfs_aformat "${SCRATCH_DEV}" "${btree_attr}" "btree"
+}
+
+# Check data fork format of ext4 file
+__populate_check_ext4_dformat() {
+ dev="$1"
+ inode="$2"
+ format="$3"
+
+ extents=0
+ etree=0
+ debugfs -R "stat <${inode}>" "${dev}" 2> /dev/null | grep 'ETB[0-9]' -q && etree=1
+ iflags="$(debugfs -R "stat <${inode}>" "${dev}" 2> /dev/null | grep 'Flags:' | sed -e 's/^.*Flags: \([0-9a-fx]*\).*$/\1/g')"
+ test "$(echo "${iflags}" | awk '{print and(strtonum($1), 0x80000);}')" -gt 0 && extents=1
+
+ case "${format}" in
+ "blockmap")
+ test "${extents}" -eq 0 || _fail "failed to create ino ${inode} with blockmap"
+ ;;
+ "extent"|"extents")
+ test "${extents}" -eq 1 || _fail "failed to create ino ${inode} with extents"
+ ;;
+ "etree")
+ (test "${extents}" -eq 1 && test "${etree}" -eq 1) || _fail "failed to create ino ${inode} with extent tree"
+ ;;
+ *)
+ _fail "Unknown dformat ${format}"
+ esac
+}
+
+# Check attr fork format of ext4 file
+__populate_check_ext4_aformat() {
+ dev="$1"
+ inode="$2"
+ format="$3"
+
+ ablock=1
+ debugfs -R "stat <${inode}>" "${dev}" 2> /dev/null | grep 'File ACL: 0' -q && ablock=0
+
+ case "${format}" in
+ "local"|"inline")
+ test "${ablock}" -eq 0 || _fail "failed to create inode ${inode} with ${format} xattr"
+ ;;
+ "block")
+ test "${extents}" -eq 1 || _fail "failed to create inode ${inode} with ${format} xattr"
+ ;;
+ *)
+ _fail "Unknown aformat ${format}"
+ esac
+}
+
+# Check structure of ext4 dir
+__populate_check_ext4_dir() {
+ dev="$1"
+ inode="$2"
+ dtype="$3"
+
+ htree=0
+ inline=0
+ iflags="$(debugfs -R "stat <${inode}>" "${dev}" 2> /dev/null | grep 'Flags:' | sed -e 's/^.*Flags: \([0-9a-fx]*\).*$/\1/g')"
+ test "$(echo "${iflags}" | awk '{print and(strtonum($1), 0x1000);}')" -gt 0 && htree=1
+ test "$(echo "${iflags}" | awk '{print and(strtonum($1), 0x10000000);}')" -gt 0 && inline=1
+
+ case "${dtype}" in
+ "inline")
+ (test "${inline}" -eq 1 && test "${htree}" -eq 0) || _fail "failed to create ${dtype} dir ino ${inode} htree ${htree} inline ${inline}"
+ ;;
+ "block")
+ (test "${inline}" -eq 0 && test "${htree}" -eq 0) || _fail "failed to create ${dtype} dir ino ${inode} htree ${htree} inline ${inline}"
+ ;;
+ "htree")
+ (test "${inline}" -eq 0 && test "${htree}" -eq 1) || _fail "failed to create ${dtype} dir ino ${inode} htree ${htree} inline ${inline}"
+ ;;
+ *)
+ _fail "Unknown directory type ${dtype}"
+ ;;
+ esac
+}
+
+# Check that populate created all the types of files we wanted
+_scratch_ext4_populate_check() {
+ _scratch_mount
+ extents_file="$(__populate_find_inode "${SCRATCH_MNT}/S_IFREG.FMT_EXTENTS")"
+ etree_file="$(__populate_find_inode "${SCRATCH_MNT}/S_IFREG.FMT_ETREE")"
+ block_dir="$(__populate_find_inode "${SCRATCH_MNT}/S_IFDIR.FMT_BLOCK")"
+ htree_dir="$(__populate_find_inode "${SCRATCH_MNT}/S_IFDIR.FMT_HTREE")"
+ extents_slink="$(__populate_find_inode "${SCRATCH_MNT}/S_IFLNK.FMT_EXTENTS")"
+ local_attr="$(__populate_find_inode "${SCRATCH_MNT}/ATTR.FMT_LOCAL")"
+ block_attr="$(__populate_find_inode "${SCRATCH_MNT}/ATTR.FMT_BLOCK")"
+ umount "${SCRATCH_MNT}"
+
+ __populate_check_ext4_dformat "${SCRATCH_DEV}" "${extents_file}" "extents"
+ __populate_check_ext4_dformat "${SCRATCH_DEV}" "${etree_file}" "etree"
+ __populate_check_ext4_dir "${SCRATCH_DEV}" "${block_dir}" "block"
+ __populate_check_ext4_dir "${SCRATCH_DEV}" "${htree_dir}" "htree"
+ __populate_check_ext4_dformat "${SCRATCH_DEV}" "${extents_slink}" "extents"
+ __populate_check_ext4_aformat "${SCRATCH_DEV}" "${local_attr}" "local"
+ __populate_check_ext4_aformat "${SCRATCH_DEV}" "${block_attr}" "block"
+}
+
+# Populate a scratch FS and check the contents to make sure we got that
+_scratch_populate() {
+ case "${FSTYP}" in
+ "xfs")
+ _scratch_xfs_populate
+ _scratch_xfs_populate_check
+ ;;
+ "ext4")
+ _scratch_ext4_populate
+ _scratch_ext4_populate_check
+ ;;
+ *)
+ _fail "Don't know how to populate a ${FSTYP} filesystem."
+ ;;
+ esac
+}
+
+# Modify various files after a fuzzing operation
+_scratch_fuzz_modify() {
+ nr="$1"
+
+ test -z "${nr}" && nr=50000
+ echo "+++ touch ${nr} files"
+ $XFS_IO_PROG -f -c "pwrite -S 0x63 0 ${BLK_SZ}" "/tmp/afile" > /dev/null
+ date="$(date)"
+ find "${SCRATCH_MNT}/" -type f 2> /dev/null | head -n "${nr}" | while read f; do
+ setfattr -n "user.date" -v "${date}" "$f"
+ cat "/tmp/afile" >> "$f"
+ mv "$f" "$f.longer"
+ done
+ rm -rf "/tmp/afile"
+
+ echo "+++ create files"
+ cp -pRdu "${SRCDIR}" "${SCRATCH_MNT}/test.moo"
+ sync
+
+ echo "+++ remove files"
+ rm -rf "${SCRATCH_MNT}/test.moo"
+ rm -rf "${SCRATCH_MNT}/test.1"
+}
+
+# Try to access files after fuzzing
+_scratch_fuzz_test() {
+ echo "+++ ls -laR" >> $seqres.full
+ ls -laR "${SCRATCH_MNT}/test.1/" >/dev/null 2>&1
+
+ echo "+++ cat files" >> $seqres.full
+ (find "${SCRATCH_MNT}/test.1/" -type f -size -1048576k -print0 | xargs -0 cat) >/dev/null 2>&1
+}
+
--
To unsubscribe from this list: send the line "unsubscribe linux-ext4" in
the body of a message to majordomo@...r.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Powered by blists - more mailing lists