/*
 * random_exercise.c --- Test program which exercises an ext2
 * 	filesystem.  It creates a lot of random files in the current
 * 	directory, while holding some files open while they are being
 * 	deleted.  This exercises the orphan list code, as well as
 * 	creating lots of fodder for the ext3 journal.
 * 
 * Copyright (C) 2000 Theodore Ts'o.
 *
 * %Begin-Header%
 * This file may be redistributed under the terms of the GNU Public
 * License.
 * %End-Header%
 */

#include <unistd.h>
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>

#define MAXFDS	128

struct state {
	char	name[16];
	int	state;
	int	isdir;
};

#define STATE_CLEAR	0
#define STATE_CREATED	1
#define STATE_DELETED	2

struct state state_array[MAXFDS];

#define DATA_SIZE 65536

char data_buffer[DATA_SIZE];

void clear_state_array()
{
	int	i;

	for (i = 0; i < MAXFDS; i++)
		state_array[i].state = STATE_CLEAR;
}

int get_random_fd()
{
	int	fd;

	while (1) {
		fd = ((int) random()) % MAXFDS;
		if (fd > 2)
			return fd;
	}
}

unsigned int get_inode_num(int fd)
{
	struct stat st;

	if (fstat(fd, &st) < 0) {
		perror("fstat");
		return 0;
	}
	return st.st_ino;
}


void create_random_file()
{
	char template[16] = "EX.XXXXXX";
	int	fd;
	int	isdir = 0;
	int	size;
	
	mktemp(template);
	isdir = random() & 1;
	if (isdir) {
		if (mkdir(template, 0700) < 0)
			return;
		fd = open(template, O_RDONLY, 0600);
		printf("Created temp directory %s, fd = %d\n",
		       template, fd);
	} else {
		size = random() & (DATA_SIZE-1);		
		fd = open(template, O_CREAT|O_RDWR, 0600);
		write(fd, data_buffer, size);
		printf("Created temp file %s, fd = %d, size=%d\n",
		       template, fd, size);
	}
	state_array[fd].isdir = isdir;
	if (fd < 0)
		return;
	state_array[fd].isdir = isdir;
	state_array[fd].state = STATE_CREATED;
	strcpy(state_array[fd].name, template);
}

void truncate_file(int fd)
{
	int	size;

	size = random() & (DATA_SIZE-1);

	if (state_array[fd].isdir)
		return;

	ftruncate(fd, size);
	printf("Truncating temp file %s, fd = %d, ino=%u, size=%d\n",
	       state_array[fd].name, fd, get_inode_num(fd), size);
}


void unlink_file(int fd)
{
	char *filename = state_array[fd].name;
	
	printf("Deleting %s, fd = %d, ino = %u\n", filename, fd,
	       get_inode_num(fd));

	if (state_array[fd].isdir)
		rmdir(filename);
	else
		unlink(filename);
	state_array[fd].state = STATE_DELETED;
}

void close_file(int fd)
{
	char *filename = state_array[fd].name;
	
	printf("Closing %s, fd = %d, ino = %u\n", filename, fd,
	       get_inode_num(fd));
	
	close(fd);
	state_array[fd].state = STATE_CLEAR;
}


main(int argc, char **argv)
{
	int	i, fd;

	memset(data_buffer, 0, sizeof(data_buffer));
	sprintf(data_buffer, "This is a test file created by the "
		"random_exerciser program\n");
	
	for (i=0; i < 100000; i++) {
		fd = get_random_fd();
		switch (state_array[fd].state) {
		case STATE_CLEAR:
			create_random_file();
			break;
		case STATE_CREATED:
			if ((state_array[fd].isdir == 0) &&
			    (random() & 2))
				truncate_file(fd);
			else
				unlink_file(fd);
			break;
		case STATE_DELETED:
			close_file(fd);
			break;
		}
	}
}


