[Ocfs2-tools-devel] [Ocfs2-test-devel] [PATCH 3/6] New set of inline-data testing tools:Add single-node testing binary for directory
Tao Ma
tao.ma at oracle.com
Sun Aug 31 23:09:58 PDT 2008
tristan.ye wrote:
> Still have sent this patch out before,
>
> just enhance the orignal inline-dirs.c become work-load tunable,to
> perform a variety of test,such as stress test. also add concurrent r/w
> and multiple directories cases.
>
> Signed-off-by: Tristan Ye <tristan.ye at oracle.com>
> ---
>
> Index: ocfs2-test/programs/inline-data/single-inline-dirs.c
> ===================================================================
> --- ocfs2-test/programs/inline-data/single-inline-dirs.c (revision 0)
> +++ ocfs2-test/programs/inline-data/single-inline-dirs.c (revision 0)
> @@ -0,0 +1,1227 @@
> +/*
> + * Verify inline directory data.
> + *
> + * All tests read back the entire directory to verify correctness.
> + *
> + * XXX: This could easily be turned into an mpi program, where a
> + * second node does the verification step.
> + */
> +
> +#define _XOPEN_SOURCE 600
> +#define _GNU_SOURCE
> +
> +#include <asm/types.h>
> +#include <sys/mman.h>
> +#include <sys/types.h>
> +#include <sys/stat.h>
> +#include <sys/vfs.h>
> +#include <sys/shm.h>
> +#include <sys/sem.h>
> +#include <unistd.h>
> +#include <fcntl.h>
> +#include <limits.h>
> +
> +#include <ocfs2/ocfs2.h>
> +
> +#include <dirent.h>
> +
> +#include <stddef.h>
> +#include <stdio.h>
> +#include <stdlib.h>
> +#include <errno.h>
> +#include <string.h>
> +
> +#include <signal.h>
> +#include <sys/wait.h>
> +#include <inttypes.h>
> +#include <linux/types.h>
> +
> +
> +#define OCFS2_MAX_FILENAME_LEN 255
> +
> +/*
> + * OCFS2_DIR_PAD defines the directory entries boundaries
> + *
> + * NOTE: It must be a multiple of 4
> + */
> +#define OCFS2_DIR_PAD 4
> +#define OCFS2_DIR_ROUND (OCFS2_DIR_PAD - 1)
> +#define OCFS2_DIR_MEMBER_LEN offsetof(struct ocfs2_dir_entry, name)
> +#define OCFS2_DIR_REC_LEN(name_len) (((name_len) + OCFS2_DIR_MEMBER_LEN
> + \
> + OCFS2_DIR_ROUND) & \
> + ~OCFS2_DIR_ROUND)
why need this? they are already defined in ocfs2_fs.h.
> +/*
> + * Quick reference table of namelen boundaries and their respective
> reclens.
> + *
> + * (name: 1 rec: 16) (name: 5 rec: 20) (name: 9 rec: 24)
> + * (name: 13 rec: 28) (name: 17 rec: 32) (name: 21 rec: 36)
> + * (name: 25 rec: 40) (name: 29 rec: 44) (name: 33 rec: 48)
> + * (name: 37 rec: 52) (name: 41 rec: 56) (name: 45 rec: 60)
> + * (name: 49 rec: 64) (name: 53 rec: 68) (name: 57 rec: 72)
> + * (name: 61 rec: 76) (name: 65 rec: 80) (name: 69 rec: 84)
> + * (name: 73 rec: 88) (name: 77 rec: 92) (name: 81 rec: 96)
> + * (name: 85 rec: 100) (name: 89 rec: 104) (name: 93 rec: 108)
> + * (name: 97 rec: 112) (name: 101 rec: 116) (name: 105 rec:
> 120)
> + * (name: 109 rec: 124) (name: 113 rec: 128) (name: 117 rec:
> 132)
> + * (name: 121 rec: 136) (name: 125 rec: 140) (name: 129 rec:
> 144)
> + * (name: 133 rec: 148) (name: 137 rec: 152) (name: 141 rec:
> 156)
> + * (name: 145 rec: 160) (name: 149 rec: 164) (name: 153 rec:
> 168)
> + * (name: 157 rec: 172) (name: 161 rec: 176) (name: 165 rec:
> 180)
> + * (name: 169 rec: 184) (name: 173 rec: 188) (name: 177 rec:
> 192)
> + * (name: 181 rec: 196) (name: 185 rec: 200) (name: 189 rec:
> 204)
> + * (name: 193 rec: 208) (name: 197 rec: 212) (name: 201 rec:
> 216)
> + * (name: 205 rec: 220) (name: 209 rec: 224) (name: 213 rec:
> 228)
> + * (name: 217 rec: 232) (name: 221 rec: 236) (name: 225 rec:
> 240)
> + * (name: 229 rec: 244) (name: 233 rec: 248) (name: 237 rec:
> 252)
> + * (name: 241 rec: 256) (name: 245 rec: 260) (name: 249 rec:
> 264)
> + * (name: 253 rec: 268)
> + */
also why you want this?
> +static int get_max_inlined_entries(int max_inline_size)
Please note that with Tiger's new xattr, max_inline_size may be changed.
so here the magic number(312 etc) may not be ok.
> +{
> + unsigned int almost_full_entries;
> +
> + /*
> + * This will create enough entries to leave only 280 free
> + * bytes in the directory.
> + *
> + * max_inline_size % 512 = 312 [always]
> + * rec overhead for '.' and '..' = 32
> + * So, 312 - 32 = 280.
> + *
> + */
> + almost_full_entries = max_inline_size / 512;
> + almost_full_entries *= 512;
> + almost_full_entries /= 32;
> +
> + /*
> + * Now we add enough 32 byte entries to fill that remaining 280
> bytes:
> + *
> + * 280 / 32 = 8
> + *
> + * And we'll be left over with 24 bytes:
> + *
> + * 280 % 32 = 24
> + *
> + * Which can easily be overflowed by adding one more 32 byte
> entry.
> + */
> + almost_full_entries += 8;
> + /*if user-specified operated_entries larger than this,decrease
> to a
> + right inlined number
> + */
> + if (operated_entries > almost_full_entries)
> + operated_entries = almost_full_entries - 1;
> +
> + return almost_full_entries;
> +
> +}
> +static void get_directory_almost_full(int minus_this_many)
> +{
> + int almost_full_entries;
> +
> + almost_full_entries = get_max_inlined_entries(max_inline_size);
> +
> + almost_full_entries -= minus_this_many;
> +
> + /* Need up to 20 characters to get a 32 byte entry */
> + create_files("filename-", almost_full_entries);
> +}
> +
> +static void random_unlink(int iters)
> +{
> + int i, ret;
> + struct my_dirent *dirent;
> +
> + while (iters > 0) {
> + i = get_rand(0, num_dirents - 1);
> + dirent = &dirents[i];
> +
> + if (is_dot_entry(dirent))
> + continue;
> + if (dirent->name_len == 0)
> + continue;
> +
> + ret = unlink_dirent(dirent);
> + if (ret) {
> + ret = errno;
> + fprintf(stderr, "unlink failure %d: %s\n", ret,
> + strerror(ret));
> + exit(ret);
> + }
> +
> + dirent->name_len = 0;
> + iters--;
> + }
> +}
> +
> +static void random_fill_empty_entries(int iters)
> +{
> + int i, ret, fd;
> + struct my_dirent *dirent;
> +
> + while (iters > 0) {
> + i = get_rand(0, num_dirents - 1);
> + dirent = &dirents[i];
> +
> + if (is_dot_entry(dirent))
> + continue;
> + if (dirent->name_len > 0)
> + continue;
> +
> + //sprintf(path1, "%s%011d", "filename-", i);
> + dirent->type = S_IFREG >> S_SHIFT;
> + dirent->name_len = strlen(dirent->name);
> + dirent->seen = 0;
> + //strcpy(dirent->name, path1);
> +
> + sprintf(path, "%s/%s", dir_name, dirent->name);
> +
> + fd = open(path, FILE_BUFFERED_RW_FLAGS, FILE_MODE);
> + if (fd == -1) {
> + ret = errno;
> + fprintf(stderr, "open failure %d: %s\n", ret, strerror(ret));
> + exit(ret);
> + }
> +
> + close(fd);
> +
> + iters--;
> + }
> +}
> +
> +static void random_rename_same_reclen(int iters)
> +{
> + int i, ret;
> + struct my_dirent *dirent;
> +
> + while (iters > 0) {
> + i = get_rand(0, num_dirents - 1);
> + dirent = &dirents[i];
> +
> + if (is_dot_entry(dirent))
> + continue;
> + if (dirent->name_len == 0)
> + continue;
> +
> + /*
> + * We already renamed this one
> + */
> + /*
> + if (dirent->name[0] == 'R')
> + continue;
> + */
> +
> + strcpy(path, dirent->name);
> + path[0] = 'R';
> + sprintf(path1, "%s/%s", dir_name, path);
> + sprintf(path, "%s/%s", dir_name, dirent->name);
> +
> + ret = rename(path, path1);
> + if (ret) {
> + ret = errno;
> + fprintf(stderr, "rename failure %d: %s\n", ret,
> + strerror(ret));
> +
> + fprintf(stderr, "Failed rename from %s to %s\n",
> + path, path1);
> +
> + exit(ret);
> + }
> + dirent->name[0] = 'R';
> + iters--;
> + }
> +}
> +
> +static void random_deleting_rename(int iters)
> +{
> + int i, j, ret;
> + struct my_dirent *dirent1, *dirent2;
> +
> + while (iters--) {
> + i = get_rand(0, num_dirents - 1);
> + j = get_rand(0, num_dirents - 1);
you can start from 2 instead of 0 so that you will not get '.' or '..'
if I read your code correctly.
> + dirent1 = &dirents[i];
> + dirent2 = &dirents[j];
> +
> + if (dirent1 == dirent2)
> + continue;
> + if (is_dot_entry(dirent1) || is_dot_entry(dirent2))
> + continue;
> + if (dirent1->name_len == 0 || dirent2->name_len == 0)
> + continue;
> +
> + sprintf(path, "%s/%s", dir_name, dirent1->name);
> + sprintf(path1, "%s/%s", dir_name, dirent2->name);
> +
> + ret = rename(path, path1);
> + if (ret) {
> + ret = errno;
> + fprintf(stderr, "rename failure %d: %s\n", ret,
> + strerror(ret));
> +
> + fprintf(stderr, "Failed rename from %s to %s\n",
> + path, path1);
> +
> + exit(ret);
> + }
> + dirent2->type = dirent1->type;
> + dirent1->name_len = 0;
> + }
> +}
> +
btw, I have seen many functions quite similar with the previous patch,
so is there any possibility that you can merge them together(I mean
create another file and link it when you create your executives)?
Regards,
Tao
More information about the Ocfs2-tools-devel
mailing list