[Ocfs2-test-devel] [PATCH 4/9] Ocfs2-test: Add utility funcs for both single-node and multi-nodes tests.

Tristan Ye tristan.ye at oracle.com
Fri Mar 20 01:24:53 PDT 2009


All common funcs shared by single-node and multi-nodes testing binaries
gathered here.

Signed-off-by: Tristan Ye <tristan.ye at oracle.com>
---
 programs/reflink_tests/reflink_test_utils.c |  980 +++++++++++++++++++++++++++
 1 files changed, 980 insertions(+), 0 deletions(-)
 create mode 100755 programs/reflink_tests/reflink_test_utils.c

diff --git a/programs/reflink_tests/reflink_test_utils.c b/programs/reflink_tests/reflink_test_utils.c
new file mode 100755
index 0000000..b5d4acb
--- /dev/null
+++ b/programs/reflink_tests/reflink_test_utils.c
@@ -0,0 +1,980 @@
+/* -*- mode: c; c-basic-offset: 8; -*-
+ * vim: noexpandtab sw=8 ts=8 sts=0:
+ *
+ * reflink_test_utils.c
+ *
+ * Provide generic utility fuctions for both single and multiple
+ * nodes refcount test on ocfs2.
+ *
+ * Written by tristan.ye at oracle.com
+ *
+ * Copyright (C) 2008 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 version 2 as published by the Free Software Foundation.
+ *
+ * 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.
+ */
+
+#include "reflink_test.h"
+
+extern char *orig_pattern;
+extern int test_flags;
+
+extern unsigned long page_size;
+extern unsigned long file_size;
+
+extern unsigned int blocksize;
+extern unsigned long clustersize;
+extern unsigned int max_inline_size;
+
+extern ocfs2_filesys *fs;
+extern struct ocfs2_super_block *ocfs2_sb;
+
+extern unsigned long get_rand(unsigned long min, unsigned long max)
+{
+	if (min == 0 && max == 0)
+		return 0;
+
+	return min + (rand() % (max - min + 1));
+}
+
+extern char rand_char(void)
+{
+        return 'A' + (char) get_rand(0, 25);
+}
+
+extern int read_at(int fd, void *buf, size_t count, off_t offset)
+{
+	int ret;
+
+	ret = pread(fd, buf, count, offset);
+	if (ret < 0) {
+		ret = errno;
+		fprintf(stderr, "read error %d: \"%s\"\n", ret, strerror(ret));
+		return -1;
+	}
+
+	return 0;
+}
+
+extern int read_at_file(char *pathname, void *buf, size_t count, off_t offset)
+{
+        int fd, ret;
+
+        fd  = open64(pathname, FILE_RO_FLAGS);
+        if (fd < 0) {
+                fd = errno;
+                fprintf(stderr, "open file %s failed:%d:%s\n", pathname, fd,
+                        strerror(fd));
+		return fd;
+        }
+
+	ret = read_at(fd, buf, count, offset);
+
+        close(fd);
+
+        return ret;
+}
+
+
+extern int mmap_read_at(int fd, char *buf, size_t count, off_t offset)
+{
+        int i, j, ret;
+        unsigned long mmap_size = page_size;
+        unsigned long size = offset + count;
+        char *region;
+
+        while (mmap_size < size)
+                mmap_size += page_size;
+
+        region = mmap(NULL, mmap_size, PROT_READ, MAP_SHARED, fd, 0);
+        if (region == MAP_FAILED) {
+                ret = errno;
+                fprintf(stderr, "mmap (read) error %d: \"%s\"\n", ret,
+                        strerror(ret));
+                return -1;
+        }
+
+        j = 0;
+        for (i = offset; i < size; i++) {
+		buf[j] = region[i];
+		j++;
+	}
+
+        munmap(region, mmap_size);
+
+        return 0;
+}
+
+extern int mmap_read_at_file(char *pathname, void *buf, size_t count,
+			     off_t offset)
+{
+        int fd, ret;
+
+        fd  = open64(pathname, FILE_RO_FLAGS);
+        if (fd < 0) {
+                fd = errno;
+                fprintf(stderr, "open file %s failed:%d:%s\n", pathname, fd,
+                        strerror(fd));
+		return fd;
+        }
+
+        ret = mmap_read_at(fd, buf, count, offset);
+
+        close(fd);
+
+        return ret;
+}
+
+
+
+extern int write_at(int fd, const void *buf, size_t count, off_t offset)
+{
+	int ret;
+
+	ret = pwrite(fd, buf, count, offset);
+        if (ret < 0) {
+                ret = errno;
+                fprintf(stderr, "write error %d: \"%s\"\n", ret, strerror(ret));
+                return -1;
+        }
+
+        if (ret != count) {
+                fprintf(stderr, "Short write: wanted %ld, got %d\n", count, ret);
+                return -1;
+        }
+
+        return 0;
+}
+
+extern int write_at_file(char *pathname, const void *buf, size_t count,
+			 off_t offset)
+{
+	int fd, ret;
+
+	fd  = open64(pathname, FILE_RW_FLAGS);
+	if (fd < 0) {
+		fd = errno;
+		fprintf(stderr, "open file %s failed:%d:%s\n", pathname, fd,
+                        strerror(fd));
+		return fd;
+
+	}
+
+	ret = write_at(fd, buf, count, offset);
+	
+	close(fd);
+
+	return ret;
+}
+
+
+extern int mmap_write_at(int fd, const char *buf, size_t count, off_t offset)
+{
+	int i, j, ret;
+	unsigned long mmap_size = page_size;
+	unsigned long size = offset + count;
+	char *region;
+
+	while (mmap_size < size)
+		mmap_size += page_size;
+
+	region = mmap(NULL, mmap_size, PROT_WRITE, MAP_SHARED, fd, 0);
+	if (region == MAP_FAILED) {
+		ret = errno;
+		fprintf(stderr, "mmap (write) error %d: \"%s\"\n", ret,
+			strerror(ret));
+		return -1;
+        }
+
+	j = 0;
+	for (i = offset; i < size; i++)
+		region[i] = buf[j++];
+
+	munmap(region, mmap_size);
+
+	return 0;
+}
+
+extern int mmap_write_at_file(char *pathname, const void *buf, size_t count,
+			      off_t offset)
+{
+        int fd, ret;
+
+        fd  = open64(pathname, FILE_RW_FLAGS);
+        if (fd < 0) {
+                fd = errno;
+                fprintf(stderr, "open file %s failed:%d:%s\n", pathname, fd,
+                        strerror(fd));
+		return fd;
+        }
+
+	ret = mmap_write_at(fd, buf, count, offset);
+
+        close(fd);
+
+        return ret;
+}
+
+
+extern int get_rand_buf(char *buf, unsigned long size)
+{
+	unsigned long i;
+	
+	for (i = 0; i < size; i++)
+		buf[i] = rand_char();
+
+	return 0;
+}
+
+extern int fill_pattern(unsigned long size)
+{
+
+        memset(orig_pattern, 0, PATTERN_SIZE);
+	get_rand_buf(orig_pattern, size);
+	return 0;
+}
+
+extern int prep_orig_file(char *file_name, unsigned long size, int once)
+{
+	int fd, fdt, ret;
+	unsigned long offset = 0, write_size = 0;
+	char tmp_path[PATH_MAX];
+
+	fd = open64(file_name, FILE_RW_FLAGS, FILE_MODE);
+	if (fd < 0) {
+		fd = errno;
+		fprintf(stderr, "create file %s failed:%d:%s\n", file_name, fd,
+			strerror(fd));
+		return fd;
+	}
+
+	/*
+	 * HUGEFILE large than 1G will not use pattern to verify
+	*/
+
+	if (size > G_SIZE) {
+
+		fill_pattern(G_SIZE);
+
+		if (once) {
+			while (offset < size) {
+				if ((offset + G_SIZE) > size)
+					write_size = size - offset;
+				else
+					write_size = G_SIZE;
+				
+				ret = write_at(fd, orig_pattern, write_size,
+					       offset);
+				if (ret < 0)
+					return ret;
+
+				offset += write_size;
+			}
+
+		} else {
+
+			snprintf(tmp_path, PATH_MAX, "%s-tmp-file", file_name);
+			fdt = open64(tmp_path, FILE_RW_FLAGS, FILE_MODE);
+
+			unlink(tmp_path);
+
+			while (offset < size) {
+
+				write_size = M_SIZE;
+				ret = write_at(fd, orig_pattern, write_size,
+					       offset);
+				if (ret < 0)
+					return ret;
+
+				ret = write_at(fdt, orig_pattern, write_size,
+					       offset);
+				if (ret < 0)
+					return ret;
+
+				offset += write_size;
+			}
+
+			close(fdt);
+		}
+
+		close(fd);
+		return 0;
+	}
+
+	/*
+	* file within 1G should use pattern to verify
+	*/
+
+	fill_pattern(size);
+
+	if (once) {
+		ret = write_at(fd, orig_pattern, size, 0);
+		if (ret < 0)
+			return ret;
+
+		close(fd);
+		return 0;
+	}
+
+	/*
+	* otherwise we need a tmp file to make extents incontiguous by
+	* writing data by turns
+	*/
+
+	snprintf(tmp_path, PATH_MAX, "%s-tmp-file", file_name);
+	fdt = open64(tmp_path, FILE_RW_FLAGS, FILE_MODE);
+	if (fdt < 0) {
+		fdt = errno;
+		fprintf(stderr, "create file %s failed:%d:%s\n", tmp_path, fdt,
+			strerror(fdt));
+		return fdt;
+	}
+
+	unlink(tmp_path);
+
+	while (offset < size) {
+		if (test_flags & RAND_TEST)
+			write_size = (size >= HUNK_SIZE * 2) ?
+				      get_rand(1, HUNK_SIZE * 2):
+				      get_rand(1, size);
+		else
+			write_size = HUNK_SIZE;
+
+		if (offset + write_size > size)
+			write_size = size - offset;
+
+		ret = write_at(fd, orig_pattern + offset, write_size, offset);
+        	if (ret < 0)
+                	return ret;
+
+		ret = write_at(fdt, orig_pattern + offset, write_size, offset);
+		if (ret < 0)
+			return ret;
+
+		offset += write_size;
+	}
+
+	close(fdt);
+	close(fd);
+
+	return 0;
+}
+
+extern int reflink(const char *oldpath, const char *newpath)
+{
+	int fd, ret;
+	struct reflink_arguments args;
+
+	args.old_path = (__u64)oldpath;
+	args.new_path = (__u64)newpath;
+
+	fd = open64(oldpath, FILE_RO_FLAGS);
+	if (fd < 0) {
+		fd = errno;
+		fprintf(stderr, "open file %s failed:%d:%s\n", oldpath, fd,
+			strerror(fd));
+		return fd;
+	}
+
+	ret = ioctl(fd, OCFS2_IOC_REFLINK, &args);
+	if (ret) {
+		ret = errno;
+		fprintf(stderr, "ioctl failed:%d:%s\n", ret, strerror(ret));
+		return ret;
+	}
+  
+	close(fd);
+
+	return 0;
+}
+
+extern int verify_reflink_pair(const char *src, const char *dest)
+{
+	int fds, fdd, ret;
+	char bufs[HUNK_SIZE], bufd[HUNK_SIZE];
+	unsigned long reads, readd;
+
+	fds = open64(src, FILE_RO_FLAGS);
+	if (fds < 0) {
+                fds = errno;
+                fprintf(stderr, "open file %s failed:%d:%s\n", src, fds,
+                        strerror(fds));
+                return fds;
+        }
+
+	fdd = open64(dest, FILE_RO_FLAGS);
+	if (fdd < 0) {
+                fdd = errno;
+                fprintf(stderr, "open file %s failed:%d:%s\n", src, fdd,
+                        strerror(fdd));
+                return fdd;
+        }
+
+	while ((reads = read(fds, bufs, HUNK_SIZE)) &&
+	       (readd = read(fdd, bufd, HUNK_SIZE))) {
+
+		if (reads != readd) {
+			fprintf(stderr, "data readed are not in the same size\n");
+			return 1;
+		}
+
+		ret = memcmp(bufs, bufd, reads);
+		if (ret) {
+			fprintf(stderr, "data readed are different\n");
+			return ret;
+		}
+	}
+
+	close(fds);
+	close(fdd);
+	
+	return 0;
+}
+
+extern int verify_pattern(char *buf, unsigned long offset, unsigned long size)
+{
+	unsigned long i;
+
+	char *start = orig_pattern + offset;
+
+	for (i = 0; i < size; i++) {
+		if (buf[i] != start[i]) {
+			fprintf(stderr, "original file verify failed at byte: "
+				"%ld\n", i);
+			return -1;
+                }
+	}
+
+	return 0;
+}
+
+
+extern int verify_orig_file(char *orig)
+{
+	int ret, fd;
+	unsigned long readed, offset = 0;
+	char buf[HUNK_SIZE];
+
+	unsigned int mmap_size = page_size;
+        void *region;
+
+	fd = open64(orig, FILE_RO_FLAGS);
+	if (fd < 0) {
+                fd = errno;
+                fprintf(stderr, "open file %s failed:%d:%s\n", orig, fd,
+                        strerror(fd));
+		return fd;
+        }
+
+	/* 
+	* use mmap read to verify original file
+	*/
+	if (test_flags & MMAP_TEST) {
+
+		while (mmap_size < file_size)
+			mmap_size += page_size;
+
+		region = mmap(NULL, mmap_size, PROT_READ, MAP_SHARED, fd, 0);
+		if (region == MAP_FAILED) {
+			ret = errno;
+			fprintf(stderr, "mmap (read) error %d: \"%s\"\n", ret,
+				strerror(ret));
+			return ret;
+		}
+
+		ret = verify_pattern(region, 0, file_size);
+		if (ret) {
+			fprintf(stderr, "Verify original file by mmap failed\n");
+			return ret;
+		}
+
+		munmap(region, mmap_size);
+		return 0;
+
+	}
+
+	while ((readed = read(fd, buf, HUNK_SIZE)) > 0) {
+		ret = verify_pattern(buf, offset, readed);
+		if (ret) {
+			fprintf(stderr, "Verify original file failed\n");
+			return ret;
+		}
+
+		offset += readed;
+	}
+	
+	close(fd);
+
+	return 0;
+}
+
+extern int do_reflinks(const char *src, const char *dest_prefix, unsigned long iter,
+		int manner)
+{
+	int ret;
+	unsigned long i, j = 0;
+	char from[PATH_MAX], to[PATH_MAX];
+
+	for (i = 0; i < iter; i++) {
+
+		snprintf(to, PATH_MAX, "%sr%ld", dest_prefix, i);
+		if (i == 0) {
+			strcpy(from, src);
+		} else {
+			if (manner == 0)
+				j = 0;
+			if (manner == 1)
+				j = i - 1;
+			if (manner > 1)
+				j = get_rand(0, i - 1);
+
+			if (j == 0)
+				strcpy(from, src);
+			else
+				snprintf(from, PATH_MAX, "%sr%ld", dest_prefix, j);
+		}
+
+		ret = reflink(from, to);
+		if (ret) {
+			fprintf(stderr, "do_reflinks failed\n");
+			return ret;
+		}
+
+	}
+	
+	return 0;
+}
+
+extern int do_reads_on_reflinks(char *ref_pfx, unsigned long iter,
+				unsigned long size, unsigned long interval)
+{
+	int ret, fd;
+	unsigned long i, read_size, offset = 0;
+	char ref_path[PATH_MAX];
+	char buf[HUNK_SIZE * 2];
+
+	for (i = 0; i < iter; i++) {
+		if ((i % 3 ) == 0)
+			continue;
+
+		snprintf(ref_path, PATH_MAX, "%sr%ld", ref_pfx, i);
+		fd = open64(ref_path, FILE_RO_FLAGS);
+		if (fd < 0) {
+			fd = errno;
+			fprintf(stderr, "open file %s failed:%d:%s\n",
+				ref_path, fd, strerror(fd));
+			return fd;
+		}
+
+		offset = 0;
+
+		while (offset < size) {
+			if (test_flags & RAND_TEST)
+				read_size = ((i % 2) == 0) ?
+					     get_rand(1, HUNK_SIZE) :
+					     get_rand(HUNK_SIZE, HUNK_SIZE * 2);
+			else
+				read_size = HUNK_SIZE;
+
+			memset(buf, 0, HUNK_SIZE * 2);
+
+			if (test_flags & MMAP_TEST) {
+
+				if ((offset + read_size) >= size)
+					break;
+
+				ret = mmap_read_at(fd, buf, read_size, offset);
+				if (ret) {
+					fprintf(stderr, "mmap_read_at failed\n");
+					return ret;
+				}
+
+			} else {
+
+				if ((offset + read_size) >= size)
+					break;
+
+				ret = read_at(fd, buf, read_size, offset);	
+				if (ret) {
+
+					fprintf(stderr, "read_at failed\n");
+					return ret;
+				}
+			}
+
+			if (test_flags & RAND_TEST) 
+				offset = offset + read_size + get_rand(0, interval);
+			else
+				offset = offset + read_size + interval;
+		}
+
+		close(fd);
+	}
+
+	return 0;
+}
+
+extern int do_cows_on_write(char *ref_pfx, unsigned long iter,
+			    unsigned long size, unsigned long interval)
+{
+	int ret, fd;
+	unsigned long i, write_size, offset = 0;
+	char ref_path[PATH_MAX];
+	char buf[HUNK_SIZE * 2];
+
+	for (i = 0; i < iter; i++) {
+		/*
+		 * leave 1/3 reflinks still shared the same extents
+		*/
+		if ((i % 3) == 0)
+			continue;
+
+		snprintf(ref_path, PATH_MAX, "%sr%ld", ref_pfx, i);
+		fd = open64(ref_path, FILE_RW_FLAGS);
+		if (fd < 0) {
+			fd = errno;
+			fprintf(stderr, "open file %s failed:%d:%s\n",
+				ref_path, fd, strerror(fd));
+			return fd;
+		}
+
+		offset = 0;
+
+		while (offset < size) {
+			if (test_flags & RAND_TEST)
+				write_size = ((i % 2) == 0) ?
+					     get_rand(1, HUNK_SIZE) :
+					     get_rand(HUNK_SIZE, HUNK_SIZE * 2);
+			else
+				write_size = HUNK_SIZE;
+
+			get_rand_buf(buf, write_size);
+	
+			if (test_flags & MMAP_TEST) {
+
+				if ((offset + write_size) >= size)
+					break;
+
+				ret = mmap_write_at(fd, buf, write_size, offset);
+				if (ret) {
+
+					fprintf(stderr, "mmap_write_at failed\n");
+					return ret;
+				}
+
+			} else {
+
+				if ((offset + write_size) >= size)
+					break;
+
+				ret = write_at(fd, buf, write_size, offset);	
+				if (ret) {
+
+					fprintf(stderr, "write_at failed\n");
+					return ret;
+				}
+			}
+
+			if (test_flags & RAND_TEST) 
+				offset = offset + write_size + get_rand(0, interval);
+			else
+				offset = offset + write_size + interval;
+		}
+
+		close(fd);
+	}
+
+	return 0;
+}
+
+extern int do_cows_on_ftruncate(char *ref_pfx, unsigned long iter,
+				unsigned long size)
+{
+	int ret, fd;
+	unsigned long i, truncate_size;
+	char ref_path[PATH_MAX];
+
+	for (i = 0; i < iter; i++) {
+		snprintf(ref_path, PATH_MAX, "%sr%ld", ref_pfx, i);
+		fd = open64(ref_path, FILE_RW_FLAGS);
+		if (fd < 0) {
+			fd = errno;
+			fprintf(stderr, "create file %s failed:%d:%s\n",
+				ref_path, fd, strerror(fd));
+			return fd;
+		}
+
+		if (test_flags & RAND_TEST)
+			truncate_size = get_rand(0, size);
+		else
+			truncate_size = (size / iter) * i;
+
+		ret = ftruncate(fd, truncate_size);
+		if (ret) {
+			ret = errno;
+			fprintf(stderr, "truncate file %s failed:%d:%s\n",
+                                ref_path, ret, strerror(ret));
+			return ret;
+		}
+
+		close(fd);
+	}
+
+	return 0;
+}
+
+extern int do_appends(char *ref_pfx, unsigned long iter)
+{
+	int ret, fd, flags = FILE_RW_FLAGS | O_APPEND;
+	unsigned long i, append_size;
+	char ref_path[PATH_MAX];
+	char buf[HUNK_SIZE];
+
+	for (i = 0; i < iter; i++) {
+		snprintf(ref_path, PATH_MAX, "%sr%ld", ref_pfx, i);
+		fd = open64(ref_path, flags);
+		if (fd < 0) {
+			fd = errno;
+			fprintf(stderr, "create file %s failed:%d:%s\n",
+				ref_path, fd, strerror(fd));
+			return fd;
+		}
+
+		if (test_flags & RAND_TEST)
+			append_size = get_rand(1, HUNK_SIZE);
+		else
+			append_size = HUNK_SIZE;
+
+		get_rand_buf(buf, append_size);
+
+		ret = write(fd, buf, append_size);
+		if (ret < 0) {
+			ret = errno;
+			fprintf(stderr, "append file %s failed:%d:%s\n",
+				ref_path, ret, strerror(ret));
+			return ret;
+		}
+
+		close(fd);
+	}
+
+	return 0;
+}
+
+extern int do_unlink(char *path)
+{
+	int ret;
+
+	ret = unlink(path);
+	if (ret < 0) {
+		ret = errno;
+		fprintf(stderr, "unlink file %s failed:%d:%s\n",
+			path, ret, strerror(ret));
+		return ret;
+	}
+
+	return 0;
+}
+
+extern int do_unlinks(char *ref_pfx, unsigned long iter)
+{
+	int ret;
+
+	unsigned long i;
+	char ref_path[PATH_MAX];
+
+	for (i = 0; i < iter; i++) {
+                snprintf(ref_path, PATH_MAX, "%sr%ld", ref_pfx, i);
+		ret = unlink(ref_path);
+		if (ret < 0) {
+			ret = errno;
+			fprintf(stderr, "unlink file %s failed:%d:%s\n",
+				ref_path, ret, strerror(ret));
+			return ret;
+		}
+	}
+
+        return 0;
+}
+
+extern int open_ocfs2_volume(char *device_name)
+{
+	int open_flags = OCFS2_FLAG_HEARTBEAT_DEV_OK | OCFS2_FLAG_RO;
+	int ret;
+	uint64_t superblock = 0, block_size = 0;
+
+	ret = ocfs2_open(device_name, open_flags, superblock, block_size,
+			 &fs);
+	if (ret < 0) {
+		fprintf(stderr, "Not a ocfs2 volume!\n");
+		return ret;
+	}
+
+	ocfs2_sb = OCFS2_RAW_SB(fs->fs_super);
+	if (!(ocfs2_sb->s_feature_incompat &
+	      OCFS2_FEATURE_INCOMPAT_REFCOUNT_TREE)) {
+		fprintf(stderr, "refcount is not supported"
+			" on this ocfs2 volume\n");
+		return -1;
+	}
+
+	blocksize = 1 << ocfs2_sb->s_blocksize_bits;
+	clustersize = 1 << ocfs2_sb->s_clustersize_bits;
+	max_inline_size = ocfs2_max_inline_data(blocksize);
+
+	return 0;
+}
+
+/*
+ * Following funcs borrowed from fill_verify_holes
+ * to test holes punching and filling in reflinks
+ *
+*/
+
+extern int prep_file_with_hole(char *name, unsigned long size)
+{
+	int ret, fd;
+
+	fd = open(name, O_RDWR|O_CREAT|O_TRUNC|O_APPEND,
+		  S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH);
+
+	if (fd < 0) {
+		fprintf(stderr, "open error %d: \"%s\"\n", errno,
+			strerror(errno));
+		return -1;
+	}
+
+	ret = ftruncate(fd, size - 1);
+	if (ret == -1) {
+
+		close(fd);
+		fprintf(stderr, "ftruncate error %d: \"%s\"\n", errno,
+			strerror(errno));
+		return -1;
+	}
+
+	ret = write(fd, "A", 1);
+
+	if (ret < 0) {
+		close(fd);
+		
+		fprintf(stderr, "write error %d: \"%s\"\n", errno,
+			strerror(errno));
+	}
+
+	close(fd);
+
+	return 0;
+
+}
+
+extern FILE *open_logfile(char *logname)
+{
+	FILE *logfile;
+
+	if (!logname)
+		logfile = stdout;
+	else
+		logfile = fopen(logname, "wa");
+
+	if (!logfile) {
+		fprintf(stderr, "Error %d creating logfile: %s\n", errno,
+			strerror(errno));
+		return NULL;
+	}
+
+	return logfile;
+}
+
+extern int log_write(FILE *logfile, struct write_unit *wu)
+{
+        int fd;
+
+        fprintf(logfile, "%c\t%lu\t%u\n", wu->w_char, wu->w_offset, wu->w_len);
+
+	fflush(logfile);
+
+	fd = fileno(logfile);
+
+	fsync(fd);
+
+	return 0;
+}
+
+extern void prep_rand_write_unit(struct write_unit *wu)
+{
+again:
+	wu->w_char = RAND_CHAR_START + (char) get_rand(0, 52);
+	wu->w_offset = get_rand(0, file_size - 1);
+	wu->w_len = (unsigned int) get_rand(1, MAX_WRITE_SIZE);
+
+	if (wu->w_offset + wu->w_len > file_size)
+		wu->w_len = file_size - wu->w_offset;
+
+	/* sometimes the random number might work out like this */
+	if (wu->w_len == 0)
+		goto again;
+
+	assert(wu->w_char >= RAND_CHAR_START && wu->w_char <= 'z');
+	assert(wu->w_len <= MAX_WRITE_SIZE);
+	assert(wu->w_len > 0);
+}
+
+extern int do_write(int fd, struct write_unit *wu)
+{
+        int ret;
+	char buf[MAX_WRITE_SIZE];
+	void *mapped;
+
+	if (test_flags & MMAP_TEST) {
+
+		mapped = mmap(0, file_size, PROT_WRITE, MAP_SHARED, fd, 0);
+		if (mapped == MAP_FAILED) {
+
+                        fprintf(stderr, "mmap error %d: \"%s\"\n", errno,
+				strerror(errno));
+			return -1;
+		}
+
+		memset(mapped + wu->w_offset, wu->w_char, wu->w_len);
+
+		munmap(mapped, file_size);
+
+		return 0;
+	}
+
+	memset(buf, wu->w_char, wu->w_len);
+	ret = pwrite(fd, buf, wu->w_len, wu->w_offset);
+	if (ret == -1) {
+		fprintf(stderr, "write error %d: \"%s\"\n", errno,
+			strerror(errno));
+		return -1;
+	}
+
+	return 0;
+}
+
+extern int do_write_file(char *fname, struct write_unit *wu)
+{
+	int fd, ret;
+
+	fd  = open64(fname, FILE_RW_FLAGS);
+	if (fd < 0) {
+		fd = errno;
+		fprintf(stderr, "open file %s failed:%d:%s\n", fname, fd,
+			strerror(fd));
+		return fd;
+	}
+
+	ret = do_write(fd, wu);
+
+	close(fd);
+
+	return ret;
+}
-- 
1.5.5




More information about the Ocfs2-test-devel mailing list