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; }