[Btrfs-devel] program I used to test xattrs

Josef Bacik jbacik at redhat.com
Thu Nov 15 12:31:38 PST 2007


Hello,

This is the little basic program I used to test xattrs.  First thing I did was
something like this

cd /mnt/btrfs-test
for i in $(seq 0 100000); do touch file_$i; done

and then run

time ./xattr-test /mnt/btrfs 0
time ./xattr-test /mnt/btrfs 1
time ./xattr-test /mnt/btrfs 2

the 0 test creates 100 xattrs for every file in the directory.  the 1 test just
does a listxattr for every file in the directory, which is enough to read in all
the xattrs.  The last test deletes all of the xattrs individually for each file.
For testing with no cache just unmount between each of these tests.  Thanks
much,

Josef


#include <sys/types.h>
#include <sys/stat.h>
#include <sys/time.h>
#include <attr/xattr.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <dirent.h>
#include <unistd.h>

static int get_dir_list(char *dir, char ***filelist)
{
	struct dirent **namelist;
	int n = 0, temp, i = 0, size = 0;
	struct stat buf;

	temp = n = scandir(dir, &namelist, NULL, alphasort);
	if (n < 0) {
		perror("scandir");
		return -1;
	}

	if (n == 2) {
		while (n--)
			free(namelist[n]);
		free(namelist);
		return n;
	}

	/* we don't want '.' or '..' */
	n -= 2;
	(*filelist) = (char **) malloc(sizeof(char *) * n);

	while (temp--) {
		int size;
		char path[200];

		if (!strcmp(namelist[temp]->d_name, "..") ||
		    !strcmp(namelist[temp]->d_name, ".")) {
			free(namelist[temp]);
			continue;
		}

		snprintf(path, 200, "%s/%s", dir, namelist[temp]->d_name);
		if (stat(path, &buf)) {
			perror("stat");
			return -1;
		}

		if (S_ISDIR(buf.st_mode)) {
			n--;
			free(namelist[temp]);
			continue;
		}

		size = strlen(dir) + namelist[temp]->d_reclen;
		(*filelist)[i] = malloc(size * sizeof(char));
		memset((*filelist)[i], 0, size * sizeof(char));

		snprintf((*filelist)[i], size * sizeof(char), "%s/%s", dir, namelist[temp]->d_name);
		i++;

		free(namelist[temp]);
	}

	free(namelist);

	return n;
}

static int xattr_create_test(int files, char **filelist)
{
	int i = 0, value_size = 8, ret;
	char name[80], *value = "myvalue\0";

	while (files--) {
		for (i = 0; i < 100; i++) {
			snprintf(name, 80, "security.josef%d\0", i);
			ret = setxattr(filelist[files], name, value,
				       value_size, 0);
			if (ret) {
				printf("error creating xattr: %d\n", errno);
				return ret;
			}
		}
	}

	return 0;
}

static int xattr_list_test(int files, char **filelist)
{
	char *buffer = NULL;
	int buf_size, str_len;

	/* since we're just testing listing, we'll just do the list */
	while (files--) {
		if (listxattr(filelist[files], NULL, 0) < 0) {
			printf("error getting xattr list: %d: %s\n", errno, filelist[files]);
			return buf_size;
		}
	}

	return 0;
}

static int xattr_delete_test(int files, char **filelist)
{
	char name[80];
	int i, ret;

	while (files--) {
		for (i = 0; i < 100; i++) {
			snprintf(name, 80, "security.josef%d\0", i);
			ret = removexattr(filelist[files], name);
			if (ret) {
				printf("error creating xattr: %d\n", errno);
				return ret;
			}
		}
	}

	return 0;
}

int main(int argc, char **argv)
{
	char dir[80], **filelist;
	double cputime;
	int ret, files, test = 0;

	if (argc != 3) {
		fprintf(stderr, "Please specify a dir to run this test in and "
			"which test to run\n");
		return 1;
	}

	snprintf(dir, 80, "%s\0", argv[1]);
	if (dir[strlen(dir)-1] = '/')
		dir[strlen(dir)-1] = '\0';
	test = (int)strtol(argv[2], NULL, 10);

	if ((files = get_dir_list(dir, &filelist)) == 0)
		return 0;

	if (test == 0) {
		printf("running xattr create test....");
		ret = xattr_create_test(files, filelist);
		if (ret) {
			printf("failure\n");
			goto out;
		}
		printf("success\n");
	} else if (test == 1) {
		printf("running xattr list test");
		ret = xattr_list_test(files, filelist);
		if (ret) {
			printf("failure\n");
			goto out;
		}
		printf("success\n");
	} else if (test == 2) {
		printf("running xattr delete test");
		ret = xattr_delete_test(files, filelist);
		if (ret) {
			printf("failure\n");
			goto out;
		}
		printf("success\n");
	}

out:
	while (files--)
		free(filelist[files]);
	free(filelist);

	return 0;
}



More information about the Btrfs-devel mailing list