From: Dave Chinner <david@fromorbit.com>
To: xfs@oss.sgi.com
Subject: [PATCH 3/3] xfsqa: Add fiemap exerciser
Date: Wed, 3 Mar 2010 17:19:22 +1100 [thread overview]
Message-ID: <1267597162-12092-4-git-send-email-david@fromorbit.com> (raw)
In-Reply-To: <1267597162-12092-1-git-send-email-david@fromorbit.com>
From: Eric Sandeen <sandeen@redhat.com>
Preliminary fiemap testing support based on a test util written by
Josef Bacik.
For now it's only run with preallocation disabled, because xfs has a
tendency to fill in holes with data blocks (EOF prealloc stuff I
think) and similar for explicit preallocation, so this is breaking
the preallocation tests for now, when it finds a "data" block where
it expects a preallocated block.
Signed-off-by: Eric Sandeen <sandeen@redhat.com>
Reviewed-by: Dave Chinner <dchinner@redhat.com>
---
225 | 62 +++++
225.out | 2 +
aclocal.m4 | 19 ++
configure.in | 2 +
group | 1 +
include/builddefs.in | 2 +
src/Makefile | 8 +
src/fiemap-tester.c | 638 ++++++++++++++++++++++++++++++++++++++++++++++++++
8 files changed, 734 insertions(+), 0 deletions(-)
create mode 100644 225
create mode 100644 225.out
create mode 100644 src/fiemap-tester.c
diff --git a/225 b/225
new file mode 100644
index 0000000..673e93e
--- /dev/null
+++ b/225
@@ -0,0 +1,62 @@
+#! /bin/sh
+# FS QA Test No. 225
+#
+# Run the fiemap (file extent mapping) tester
+#
+#-----------------------------------------------------------------------
+# Copyright (c) 2009 Eric Sandeen. 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
+#-----------------------------------------------------------------------
+#
+# creator
+owner=sandeen@sandeen.net
+
+seq=`basename $0`
+echo "QA output created by $seq"
+
+here=`pwd`
+tmp=tmp/$$
+status=1 # failure is the default!
+trap "_cleanup; exit \$status" 0 1 2 3 15
+
+_cleanup()
+{
+ cd /
+ rm -f $tmp.*
+ _cleanup_testdir
+}
+
+# get standard environment, filters and checks
+. ./common.rc
+. ./common.filter
+
+# real QA test starts here
+_supported_fs generic
+_supported_os Linux
+
+_setup_testdir
+
+fiemapfile=$TEST_DIR/fiemap.$$
+
+[ -x $here/src/fiemap-tester ] || _notrun "fiemap-tester not built"
+
+echo "fiemap run without preallocation"
+$here/src/fiemap-tester -q -p 0 -r 200 /mnt/test/fiemapfile
+
+rm -f $fiemapfile
+rm -f $seq.full
+
+status=0
+exit
diff --git a/225.out b/225.out
new file mode 100644
index 0000000..7bc9312
--- /dev/null
+++ b/225.out
@@ -0,0 +1,2 @@
+QA output created by 225
+fiemap run without preallocation
diff --git a/aclocal.m4 b/aclocal.m4
index 02f56f2..6457d39 100644
--- a/aclocal.m4
+++ b/aclocal.m4
@@ -11,6 +11,25 @@
# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
# PARTICULAR PURPOSE.
+AC_DEFUN([AC_PACKAGE_WANT_LINUX_FIEMAP_H],
+ [ AC_CHECK_HEADERS([linux/fiemap.h], [ have_fiemap=true ], [ have_fiemap=false ])
+ AC_SUBST(have_fiemap)
+ ])
+
+AC_DEFUN([AC_PACKAGE_WANT_FALLOCATE],
+ [ AC_MSG_CHECKING([for fallocate])
+ AC_TRY_LINK([
+#define _GNU_SOURCE
+#define _FILE_OFFSET_BITS 64
+#include <fcntl.h>
+#include <linux/falloc.h>
+ ], [
+ fallocate(0, 0, 0, 0);
+ ], have_fallocate=yes
+ AC_MSG_RESULT(yes),
+ AC_MSG_RESULT(no))
+ AC_SUBST(have_fallocate)
+ ])
m4_include([m4/multilib.m4])
m4_include([m4/package_acldev.m4])
m4_include([m4/package_aiodev.m4])
diff --git a/configure.in b/configure.in
index 0d6f153..45b7fd1 100644
--- a/configure.in
+++ b/configure.in
@@ -64,6 +64,8 @@ in
AC_PACKAGE_WANT_GDBM
AC_PACKAGE_WANT_AIO
AC_PACKAGE_WANT_DMAPI
+ AC_PACKAGE_WANT_LINUX_FIEMAP_H
+ AC_PACKAGE_WANT_FALLOCATE
;;
esac
diff --git a/group b/group
index 5d675f0..8d4a83a 100644
--- a/group
+++ b/group
@@ -338,3 +338,4 @@ deprecated
222 auto fsr ioctl quick
223 auto quick
224 auto
+225 auto quick
diff --git a/include/builddefs.in b/include/builddefs.in
index 23a4991..3bea050 100644
--- a/include/builddefs.in
+++ b/include/builddefs.in
@@ -60,6 +60,8 @@ HAVE_DB = @have_db@
HAVE_AIO = @have_aio@
HAVE_DMAPI = @have_dmapi@
HAVE_ATTR_LIST = @have_attr_list@
+HAVE_FIEMAP = @have_fiemap@
+HAVE_FALLOCATE = @have_fallocate@
GCCFLAGS = -funsigned-char -fno-strict-aliasing -Wall
diff --git a/src/Makefile b/src/Makefile
index d86d50a..2f95fe2 100644
--- a/src/Makefile
+++ b/src/Makefile
@@ -25,6 +25,14 @@ ifeq ($(HAVE_XLOG_ASSIGN_LSN), true)
LINUX_TARGETS += loggen
endif
+ifeq ($(HAVE_FIEMAP), true)
+LINUX_TARGETS += fiemap-tester
+endif
+
+ifeq ($(HAVE_FALLOCATE),yes)
+LCFLAGS += -DHAVE_FALLOCATE
+endif
+
IRIX_TARGETS = open_unlink
ifeq ($(PKG_PLATFORM),linux)
diff --git a/src/fiemap-tester.c b/src/fiemap-tester.c
new file mode 100644
index 0000000..69016a9
--- /dev/null
+++ b/src/fiemap-tester.c
@@ -0,0 +1,638 @@
+/*
+ * Copyright (c) 2009 Josef Bacik
+ * 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 V2
+ * 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
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <string.h>
+#include <ctype.h>
+#include <sys/ioctl.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/vfs.h>
+#include <linux/fs.h>
+#include <linux/types.h>
+#include <linux/fiemap.h>
+
+/* Global for non-critical message suppression */
+int quiet;
+
+static void
+usage(void)
+{
+ printf("Usage: fiemap-tester [-m map] [-r number of runs] [-s seed] [-q]");
+#ifdef HAVE_FALLOCATE
+ printf("[-p preallocate (1/0)] ");
+#endif
+ printf("filename\n");
+ printf(" -m map : generate a file with the map given and test\n");
+#ifdef HAVE_FALLOCATE
+ printf(" -p 0/1 : turn block preallocation on or off\n");
+#endif
+ printf(" -r count : number of runs to execute (default infinity)\n");
+ printf(" -s seed : seed for random map generator (default 1)\n");
+ printf(" -q : be quiet about non-errors\n");
+ printf("-m and -r cannot be used together\n");
+ exit(EXIT_FAILURE);
+}
+
+static char *
+generate_file_mapping(int blocks, int prealloc)
+{
+ char *map;
+ int num_types = 2, cur_block = 0;
+ int i = 0;
+
+ map = malloc(sizeof(char) * blocks);
+ if (!map)
+ return NULL;
+
+ if (prealloc)
+ num_types++;
+
+
+ for (i = 0; i < blocks; i++) {
+ long num = random() % num_types;
+ switch (num) {
+ case 0:
+ map[cur_block] = 'D';
+ break;
+ case 1:
+ map[cur_block] = 'H';
+ break;
+ case 2:
+ map[cur_block] = 'P';
+ break;
+ }
+ cur_block++;
+ }
+
+ return map;
+}
+
+static int
+create_file_from_mapping(int fd, char *map, int blocks, int blocksize)
+{
+ int cur_offset = 0, ret = 0, bufsize;
+ char *buf;
+ int i = 0;
+
+ bufsize = sizeof(char) * blocksize;
+ buf = malloc(bufsize);
+ if (!buf)
+ return -1;
+
+ memset(buf, 'a', bufsize);
+
+ for (i = 0; i < blocks; i++) {
+ switch (map[i]) {
+ case 'D':
+ ret = write(fd, buf, bufsize);
+ if (ret < bufsize) {
+ printf("Short write\n");
+ ret = -1;
+ goto out;
+ }
+ break;
+#ifdef HAVE_FALLOCATE
+ case 'P':
+ ret = fallocate(fd, 0, cur_offset, blocksize);
+ if (ret < 0) {
+ printf("Error fallocating\n");
+ goto out;
+ }
+ /* fallthrough; seek to end of prealloc space */
+#endif
+ case 'H':
+ ret = lseek(fd, blocksize, SEEK_CUR);
+ if (ret == (off_t)-1) {
+ printf("Error lseeking\n");
+ ret = -1;
+ goto out;
+ }
+ break;
+ default:
+ printf("Hrm, unrecognized flag in map\n");
+ ret = -1;
+ goto out;
+ }
+ cur_offset += blocksize;
+ }
+
+ ret = 0;
+out:
+ return ret;
+}
+
+static void
+show_extent_block(struct fiemap_extent *extent, int blocksize)
+{
+ __u64 logical = extent->fe_logical;
+ __u64 phys = extent->fe_physical;
+ __u64 length = extent->fe_length;
+ int flags = extent->fe_flags;
+
+ printf("logical: [%8llu..%8llu] phys: %8llu..%8llu "
+ "flags: 0x%03X tot: %llu\n",
+ logical / blocksize, (logical + length - 1) / blocksize,
+ phys / blocksize, (phys + length - 1) / blocksize,
+ flags,
+ (length / blocksize));
+}
+
+static void
+show_extents(struct fiemap *fiemap, int blocksize)
+{
+ unsigned int i;
+
+ for (i = 0; i < fiemap->fm_mapped_extents; i++)
+ show_extent_block(&fiemap->fm_extents[i], blocksize);
+}
+
+static int
+check_flags(struct fiemap *fiemap, int blocksize)
+{
+ struct fiemap_extent *extent;
+ __u64 aligned_offset, aligned_length;
+ int c;
+
+ for (c = 0; c < fiemap->fm_mapped_extents; c++) {
+ extent = &fiemap->fm_extents[c];
+
+ aligned_offset = extent->fe_physical & ~((__u64)blocksize - 1);
+ aligned_length = extent->fe_length & ~((__u64)blocksize - 1);
+
+ if ((aligned_offset != extent->fe_physical ||
+ aligned_length != extent->fe_length) &&
+ !(extent->fe_flags & FIEMAP_EXTENT_NOT_ALIGNED)) {
+ printf("ERROR: FIEMAP_EXTENT_NOT_ALIGNED is not set "
+ "but the extent is unaligned: %llu\n",
+ (unsigned long long)
+ (extent->fe_logical / blocksize));
+ return -1;
+ }
+
+ if (extent->fe_flags & FIEMAP_EXTENT_DATA_ENCRYPTED &&
+ !(extent->fe_flags & FIEMAP_EXTENT_ENCODED)) {
+ printf("ERROR: FIEMAP_EXTENT_DATA_ENCRYPTED is set, "
+ "but FIEMAP_EXTENT_ENCODED is not set: %llu\n",
+ (unsigned long long)
+ (extent->fe_logical / blocksize));
+ return -1;
+ }
+
+ if (extent->fe_flags & FIEMAP_EXTENT_NOT_ALIGNED &&
+ aligned_offset == extent->fe_physical &&
+ aligned_length == extent->fe_length) {
+ printf("ERROR: FIEMAP_EXTENT_NOT_ALIGNED is set but "
+ "offset and length is blocksize aligned: "
+ "%llu\n",
+ (unsigned long long)
+ (extent->fe_logical / blocksize));
+ return -1;
+ }
+
+ if (extent->fe_flags & FIEMAP_EXTENT_LAST &&
+ c + 1 < fiemap->fm_mapped_extents) {
+ printf("ERROR: FIEMAP_EXTENT_LAST is set but there are"
+ " more extents left: %llu\n",
+ (unsigned long long)
+ (extent->fe_logical / blocksize));
+ return -1;
+ }
+
+ if (extent->fe_flags & FIEMAP_EXTENT_DELALLOC &&
+ !(extent->fe_flags & FIEMAP_EXTENT_UNKNOWN)) {
+ printf("ERROR: FIEMAP_EXTENT_DELALLOC is set but "
+ "FIEMAP_EXTENT_UNKNOWN is not set: %llu\n",
+ (unsigned long long)
+ (extent->fe_logical / blocksize));
+ return -1;
+ }
+
+ if (extent->fe_flags & FIEMAP_EXTENT_DATA_INLINE &&
+ !(extent->fe_flags & FIEMAP_EXTENT_NOT_ALIGNED)) {
+ printf("ERROR: FIEMAP_EXTENT_DATA_INLINE is set but "
+ "FIEMAP_EXTENT_NOT_ALIGNED is not set: %llu\n",
+ (unsigned long long)
+ (extent->fe_logical / blocksize));
+ return -1;
+ }
+
+ if (extent->fe_flags & FIEMAP_EXTENT_DATA_TAIL &&
+ !(extent->fe_flags & FIEMAP_EXTENT_NOT_ALIGNED)) {
+ printf("ERROR: FIEMAP_EXTENT_DATA_TAIL is set but "
+ "FIEMAP_EXTENT_NOT_ALIGNED is not set: %llu\n",
+ (unsigned long long)
+ (extent->fe_logical / blocksize));
+ return -1;
+ }
+ }
+
+ return 0;
+}
+
+static int
+check_data(struct fiemap *fiemap, __u64 logical_offset, int blocksize,
+ int last, int prealloc)
+{
+ struct fiemap_extent *extent;
+ __u64 orig_offset = logical_offset;
+ int c, found = 0;
+
+ for (c = 0; c < fiemap->fm_mapped_extents; c++) {
+ __u64 start, end;
+ extent = &fiemap->fm_extents[c];
+
+ start = extent->fe_logical;
+ end = extent->fe_logical + extent->fe_length;
+
+ if (logical_offset > end)
+ continue;
+
+ if (logical_offset + blocksize < start)
+ break;
+
+ if (logical_offset >= start &&
+ logical_offset < end) {
+ if (prealloc &&
+ !(extent->fe_flags & FIEMAP_EXTENT_UNWRITTEN)) {
+ printf("ERROR: preallocated extent is not "
+ "marked with FIEMAP_EXTENT_UNWRITTEN: "
+ "%llu\n",
+ (unsigned long long)
+ (start / blocksize));
+ return -1;
+ }
+
+ if (logical_offset + blocksize > end) {
+ logical_offset = end+1;
+ continue;
+ } else {
+ found = 1;
+ break;
+ }
+ }
+ }
+
+ if (!found) {
+ printf("ERROR: couldn't find extent at %llu\n",
+ (unsigned long long)(orig_offset / blocksize));
+ } else if (last &&
+ !(fiemap->fm_extents[c].fe_flags & FIEMAP_EXTENT_LAST)) {
+ printf("ERROR: last extent not marked as last: %llu\n",
+ (unsigned long long)(orig_offset / blocksize));
+ found = 0;
+ }
+
+ return (!found) ? -1 : 0;
+}
+
+static int
+check_weird_fs_hole(int fd, __u64 logical_offset, int blocksize)
+{
+ static int warning_printed = 0;
+ int block, i;
+ size_t buf_len = sizeof(char) * blocksize;
+ char *buf;
+
+ block = (int)(logical_offset / blocksize);
+ if (ioctl(fd, FIBMAP, &block) < 0) {
+ perror("Can't fibmap file");
+ return -1;
+ }
+
+ if (!block) {
+ printf("ERROR: FIEMAP claimed there was data at a block "
+ "which should be a hole, and FIBMAP confirmend that "
+ "it is in fact a hole, so FIEMAP is wrong: %llu\n",
+ (unsigned long long)(logical_offset / blocksize));
+ return -1;
+ }
+
+ buf = malloc(buf_len);
+ if (!buf) {
+ perror("Could not allocate temporary buffer");
+ return -1;
+ }
+
+ if (pread(fd, buf, buf_len, (off_t)logical_offset) < 0) {
+ perror("Error reading from file");
+ free(buf);
+ return -1;
+ }
+
+ for (i = 0; i < buf_len; i++) {
+ if (buf[i] != 0) {
+ printf("ERROR: FIEMAP claimed there was data (%c) at "
+ "block %llu that should have been a hole, and "
+ "FIBMAP confirmed that it was allocated, but "
+ "it should be filled with 0's, but it was not "
+ "so you have a big problem!\n",
+ buf[i],
+ (unsigned long long)(logical_offset / blocksize));
+ free(buf);
+ return -1;
+ }
+ }
+
+ if (warning_printed || quiet) {
+ free(buf);
+ return 0;
+ }
+
+ printf("HEY FS PERSON: your fs is weird. I specifically wanted a\n"
+ "hole and you allocated a block anyway. FIBMAP confirms that\n"
+ "you allocated a block, and the block is filled with 0's so\n"
+ "everything is kosher, but you still allocated a block when\n"
+ "didn't need to. This may or may not be what you wanted,\n"
+ "which is why I'm only printing this message once, in case\n"
+ "you didn't do it on purpose. This was at block %llu.\n",
+ (unsigned long long)(logical_offset / blocksize));
+ warning_printed = 1;
+ free(buf);
+
+ return 0;
+}
+
+static int
+check_hole(struct fiemap *fiemap, int fd, __u64 logical_offset, int blocksize)
+{
+ struct fiemap_extent *extent;
+ int c;
+
+ for (c = 0; c < fiemap->fm_mapped_extents; c++) {
+ __u64 start, end;
+ extent = &fiemap->fm_extents[c];
+
+ start = extent->fe_logical;
+ end = extent->fe_logical + extent->fe_length;
+
+ if (logical_offset > end)
+ continue;
+ if (logical_offset + blocksize < start)
+ break;
+
+ if (logical_offset >= start &&
+ logical_offset < end) {
+
+ if (check_weird_fs_hole(fd, logical_offset,
+ blocksize) == 0)
+ break;
+
+ printf("ERROR: found an allocated extent where a hole "
+ "should be: %llu\n",
+ (unsigned long long)(start / blocksize));
+ return -1;
+ }
+ }
+
+ return 0;
+}
+
+static int
+compare_fiemap_and_map(int fd, char *map, int blocks, int blocksize)
+{
+ struct fiemap *fiemap;
+ char *fiebuf;
+ int blocks_to_map, ret, cur_extent = 0, last_data;
+ __u64 map_start, map_length;
+ int i, c;
+
+ blocks_to_map = (random() % blocks) + 1;
+ fiebuf = malloc(sizeof(struct fiemap) +
+ (blocks_to_map * sizeof(struct fiemap_extent)));
+ if (!fiebuf) {
+ perror("Could not allocate fiemap buffers");
+ return -1;
+ }
+
+ fiemap = (struct fiemap *)fiebuf;
+ map_start = 0;
+ map_length = blocks_to_map * blocksize;
+
+ for (i = 0; i < blocks; i++) {
+ if (map[i] != 'H')
+ last_data = i;
+ }
+
+ fiemap->fm_flags = FIEMAP_FLAG_SYNC;
+ fiemap->fm_extent_count = blocks_to_map;
+ fiemap->fm_mapped_extents = 0;
+
+ do {
+ fiemap->fm_start = map_start;
+ fiemap->fm_length = map_length;
+
+ ret = ioctl(fd, FS_IOC_FIEMAP, (unsigned long)fiemap);
+ if (ret < 0) {
+ perror("FIEMAP ioctl failed");
+ free(fiemap);
+ return -1;
+ }
+
+ if (check_flags(fiemap, blocksize))
+ goto error;
+
+ for (i = cur_extent, c = 1; i < blocks; i++, c++) {
+ __u64 logical_offset = i * blocksize;
+
+ if (c > blocks_to_map)
+ break;
+
+ switch (map[i]) {
+ case 'D':
+ if (check_data(fiemap, logical_offset,
+ blocksize, last_data == i, 0))
+ goto error;
+ break;
+ case 'H':
+ if (check_hole(fiemap, fd, logical_offset,
+ blocksize))
+ goto error;
+ break;
+ case 'P':
+ if (check_data(fiemap, logical_offset,
+ blocksize, last_data == i, 1))
+ goto error;
+ break;
+ default:
+ printf("ERROR: weird value in map: %c\n",
+ map[i]);
+ goto error;
+ }
+ }
+ cur_extent = i;
+ map_start = i * blocksize;
+ } while (cur_extent < blocks);
+
+ ret = 0;
+ return ret;
+error:
+ printf("map is '%s'\n", map);
+ show_extents(fiemap, blocksize);
+ return -1;
+}
+
+int
+main(int argc, char **argv)
+{
+ int blocksize = 0; /* filesystem blocksize */
+ int fd; /* file descriptor */
+ int opt;
+ int rc;
+ char *fname; /* filename to map */
+ char *map = NULL; /* file map to generate */
+ int runs = -1; /* the number of runs to have */
+ int blocks = 0; /* the number of blocks to generate */
+ int maxblocks = 0; /* max # of blocks to create */
+ int prealloc = 1; /* whether or not to do preallocation */
+ int seed = 1;
+
+ while ((opt = getopt(argc, argv, "m:r:s:p:q")) != -1) {
+ switch(opt) {
+ case 'm':
+ map = strdup(optarg);
+ break;
+ case 'p':
+ prealloc = atoi(optarg);;
+#ifndef HAVE_FALLOCATE
+ if (prealloc)
+ printf("Not built with preallocation support\n");
+ usage();
+#endif
+ break;
+ case 'q':
+ quiet = 1;
+ break;
+ /* sync file before mapping */
+ case 'r':
+ runs = atoi(optarg);
+ break;
+ case 's':
+ seed = atoi(optarg);
+ break;
+ default:
+ usage();
+ }
+ }
+
+ if (runs != -1 && map)
+ usage();
+
+ fname = argv[optind++];
+ if (!fname)
+ usage();
+
+ fd = open(fname, O_RDWR|O_CREAT|O_TRUNC, 0644);
+ if (fd < 0) {
+ perror("Can't open file");
+ exit(1);
+ }
+
+ if (ioctl(fd, FIGETBSZ, &blocksize) < 0) {
+ perror("Can't get filesystem block size");
+ close(fd);
+ exit(1);
+ }
+
+#ifdef HAVE_FALLOCATE
+ /* if fallocate passes, then we can do preallocation, else not */
+ if (prealloc) {
+ prealloc = !((int)fallocate(fd, 0, 0, blocksize));
+ if (!prealloc)
+ printf("preallocation not supported, disabling\n");
+ }
+#else
+ prealloc = 0;
+#endif
+
+ if (ftruncate(fd, 0)) {
+ perror("Can't truncate file");
+ close(fd);
+ exit(1);
+ }
+
+ if (map) {
+ blocks = strlen(map);
+ runs = 0;
+ }
+
+ srandom(seed);
+
+ /* max file size 2mb / block size */
+ maxblocks = (2 * 1024 * 1024) / blocksize;
+
+ if (runs == -1)
+ printf("Starting infinite run, if you don't see any output "
+ "then its working properly.\n");
+ do {
+ if (!map) {
+ blocks = random() % maxblocks;
+ if (blocks == 0) {
+ if (!quiet)
+ printf("Skipping 0 length file\n");
+ continue;
+ }
+
+ map = generate_file_mapping(blocks, prealloc);
+ if (!map) {
+ printf("Could not create map\n");
+ exit(1);
+ }
+ }
+
+ rc = create_file_from_mapping(fd, map, blocks, blocksize);
+ if (rc) {
+ perror("Could not create file\n");
+ free(map);
+ close(fd);
+ exit(1);
+ }
+
+ rc = compare_fiemap_and_map(fd, map, blocks, blocksize);
+ if (rc) {
+ printf("Problem comparing fiemap and map\n");
+ free(map);
+ close(fd);
+ exit(1);
+ }
+
+ free(map);
+ map = NULL;
+
+ if (ftruncate(fd, 0)) {
+ perror("Could not truncate file\n");
+ close(fd);
+ exit(1);
+ }
+
+ if (lseek(fd, 0, SEEK_SET)) {
+ perror("Could not seek set\n");
+ close(fd);
+ exit(1);
+ }
+
+ if (runs) runs--;
+ } while (runs != 0);
+
+ close(fd);
+
+ return 0;
+}
--
1.6.5
_______________________________________________
xfs mailing list
xfs@oss.sgi.com
http://oss.sgi.com/mailman/listinfo/xfs
next prev parent reply other threads:[~2010-03-03 6:18 UTC|newest]
Thread overview: 11+ messages / expand[flat|nested] mbox.gz Atom feed top
2010-03-03 6:19 [PATCH 0/3] xfsqa: new tests and fixes Dave Chinner
2010-03-03 6:19 ` [PATCH 1/3] xfsqa: add delayed allocation @ ENOSPC exerciser Dave Chinner
2010-03-03 12:56 ` Christoph Hellwig
2010-03-03 22:31 ` Dave Chinner
2010-03-04 7:57 ` Christoph Hellwig
2010-03-03 6:19 ` [PATCH 2/3] xfsqa: fix size specification for scratch mkfs Dave Chinner
2010-03-03 12:58 ` Christoph Hellwig
2010-03-03 16:21 ` Eric Sandeen
2010-03-03 22:56 ` Dave Chinner
2010-03-03 6:19 ` Dave Chinner [this message]
2010-03-03 12:58 ` [PATCH 3/3] xfsqa: Add fiemap exerciser Christoph Hellwig
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=1267597162-12092-4-git-send-email-david@fromorbit.com \
--to=david@fromorbit.com \
--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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.