Commit a2ffacb0 authored by Gabriel Krisman Bertazi's avatar Gabriel Krisman Bertazi
Browse files

mem_opt

parent 39a7dc69
......@@ -8,6 +8,8 @@
#include <syscall.h>
#include <fcntl.h>
#define PAGE_SIZE (4096*4)
struct created_name;
struct dentry;
struct inotify_watcher;
......@@ -28,14 +30,20 @@ struct dentry {
struct inotify_watcher *watcher;
struct {
size_t *sizes;
struct linux_dirent64 **dirents;
int npage_dirent;
char **pages;
int *sizes;
int offset;
int npages;
int sg_len;
} sg;
struct created_name *created;
};
struct record {
int rec_len;
char key[0];
};
/* unintercepted syscall hooks */
static inline int ni_getdents64(unsigned int fd, char *buffer,
......@@ -71,7 +79,9 @@ struct dentry *dcache_lookup(const struct dentry*, char *component);
struct dentry *dentry_create(char *component, struct dentry *parent);
void dentry_destroy(struct dentry *dentry);
void dcache_add(struct dentry *dentry);
int dcache_add_dirdents(struct dentry *d, struct linux_dirent64 *buffer, int size);
int dcache_add_record(struct dentry *d, const char *component, int len);
int dcache_fill_record_page(struct dentry *d, const char *buffer, int len);
void dentry_add_file(struct dentry *dentry, const char *component, int len);
int dentry_lookup_created(struct dentry *parent, char *component, char **ci_name);
......
......@@ -97,34 +97,41 @@ void dcache_add(struct dentry *dentry)
}
}
int dcache_add_dirdents(struct dentry *d, struct linux_dirent64 *buffer, int size)
int dcache_add_record(struct dentry *d, const char *component, int len)
{
if (d->sg.npage_dirent >= d->sg.sg_len) {
void *tmp_buf, *tmp_sizes;
d->sg.sg_len = d->sg.sg_len << 1;
tmp_buf = realloc(d->sg.dirents, d->sg.sg_len *
sizeof(struct linux_dirent64*));
if (!tmp_buf) {
d->sg.sg_len = d->sg.sg_len >> 1;
return -ENOMEM;
}
d->sg.dirents = tmp_buf;
tmp_sizes = realloc(d->sg.sizes, d->sg.sg_len * sizeof(int));
if (!tmp_sizes) {
d->sg.sg_len = d->sg.sg_len >> 1;
return -ENOMEM;
}
d->sg.sizes = tmp_sizes;
int rec_len = sizeof(struct record) + len;
struct record *record;
char *page;
if ((d->sg.offset + rec_len) >= PAGE_SIZE) {
d->sg.pages[d->sg.npages] = malloc(PAGE_SIZE);
d->sg.offset = 0;
d->sg.npages += 1;
}
page = d->sg.pages[d->sg.npages - 1];
record = (struct record *) &(page[d->sg.offset]);
d->sg.dirents[d->sg.npage_dirent] = buffer;
d->sg.sizes[d->sg.npage_dirent] = size;
d->sg.npage_dirent++;
record->rec_len = rec_len;
memcpy(record->key, component, len);
d->sg.offset += rec_len;
d->sg.sizes[d->sg.npages - 1] = d->sg.offset;
return 0;
}
int dcache_fill_record_page(struct dentry *d, const char *buffer, int len)
{
struct linux_dirent64 *dirent;
int nrec = 0;
for (int off = 0; off < len; off += dirent->d_reclen) {
dirent = (struct linux_dirent64 *) (buffer + off);
dcache_add_record(d, dirent->d_name, strlen(dirent->d_name) + 1);
nrec += 1;
}
return nrec;
}
int dentry_lookup_created(struct dentry *parent, char *component,
char **ci_name)
{
......@@ -159,14 +166,15 @@ struct dentry *dentry_create(char *component, struct dentry *parent)
d->component = component;
d->parent = parent;
d->sg.npage_dirent = 0;
d->sg.sg_len = 100;
d->created = NULL;
d->watcher = NULL;
d->sg.dirents = calloc(d->sg.sg_len,
sizeof(struct linux_dirent64 *));
if (!d->sg.dirents)
d->sg.npages = 0;
d->sg.offset = PAGE_SIZE;
d->sg.sg_len = 100;
d->sg.pages = malloc(d->sg.sg_len *
sizeof(struct linux_dirent64 *));
if (!d->sg.pages)
goto fail_dirents;
d->sg.sizes = malloc(d->sg.sg_len * sizeof(int));
......@@ -176,7 +184,7 @@ struct dentry *dentry_create(char *component, struct dentry *parent)
return d;
fail_sizes:
free(d->sg.dirents);
free(d->sg.pages);
fail_dirents:
free(d);
return NULL;
......@@ -195,12 +203,12 @@ void dentry_destroy(struct dentry *d)
free(tmp);
}
for (i = 0; i < d->sg.npage_dirent; i++)
free(d->sg.dirents[i]);
for (i = 0; i < d->sg.npages; i++)
free(d->sg.pages[i]);
if (d->watcher)
inotify_destroy_watcher(d->watcher);
free(d->sg.dirents);
free(d->sg.pages);
free(d->sg.sizes);
free(d);
......
......@@ -16,14 +16,18 @@
#define print_debug(str)
#endif
static struct linux_dirent64 *search_block(char *ciname, char *buffer, int size)
int test = 0;
struct record *search_page(char *ciname, char *page, int page_len)
{
int off;
struct linux_dirent64 *dentry;
for (off = 0; off < size; off += dentry->d_reclen) {
dentry = (struct linux_dirent64 *) (buffer + off);
if (strcasecmp(dentry->d_name, ciname) == 0) {
return dentry;
struct record *record;
for (off = 0; off < page_len; off += record->rec_len) {
record = (struct record *) (page + off);
if (strcasecmp(record->key, ciname) == 0) {
return record;
}
}
return NULL;
......@@ -32,38 +36,49 @@ static struct linux_dirent64 *search_block(char *ciname, char *buffer, int size)
static int ci_lookup_fast(const struct dentry *parent, char *component,
char **ci_name)
{
struct record *record;
int i;
struct linux_dirent64 *dentry;
test = 0;
for (i = 0; i < parent->sg.npages ; i++) {
char *page = (char *) parent->sg.pages[i];
for (i = 0; i < parent->sg.npage_dirent; i++) {
char *buffer = (char *) parent->sg.dirents[i];
dentry = search_block(component, buffer, parent->sg.sizes[i]);
if (dentry) {
*ci_name = dentry->d_name;
record = search_page(component, page, parent->sg.sizes[i]);
if (record) {
*ci_name = record->key;
return 1;
}
}
if (test == 1000) {
print_debug("read 1000 records\n");
}
else if (test > 900) {
print_debug("read over 900 records\n");
}
else {
print_debug("read less than all of records\n");
}
return 0;
}
static int dentry_fill_dirents(struct dentry *dentry)
{
struct linux_dirent64 *buffer;
int nread;
ssize_t bufsiz = 4096 * 4;
char *buffer = malloc(bufsiz);
int nread;
for(;;) {
buffer = malloc(bufsiz);
if (!buffer)
break;
nread = ni_getdents64(dentry->fd, (char*) buffer, bufsiz);
if (nread <= 0) {
free (buffer);
break;
}
dcache_add_dirdents(dentry, buffer, nread);
dcache_fill_record_page(dentry, buffer, nread);
}
return 0;
}
......@@ -74,7 +89,7 @@ static inline int ci_lookup(struct dentry *parent, char *component,
if (dentry_lookup_created(parent, component, ci_name) == 1)
return 1;
}
if (parent->sg.npage_dirent == 0)
if (parent->sg.npages == 0)
dentry_fill_dirents(parent);
return ci_lookup_fast(parent, component, ci_name);
......@@ -164,8 +179,6 @@ static int search_ci_path(struct dentry *parent, char *path, char *rpath)
}
/* there is a CI component with exact path in r. Success*/
out_close_parent:
if (parent != dentry)
close(dentry->fd);
out:
return ret;
}
......@@ -209,12 +222,12 @@ static int syscall_hook(long syscall_number, long arg0, long arg1,
strncpy(original_path, &(*path)[parent_index+1], PATH_MAX);
r = search_ci_path(mnt, original_path, rpath);
print_debug(*path);
print_debug("\n");
/* print_debug(*path); */
/* print_debug("\n"); */
if (r >= 0)
*path = rpath;
print_debug(*path);
print_debug("\n\n");
/* print_debug(*path); */
/* print_debug("\n\n"); */
*result = syscall_no_intercept(syscall_number, arg0, arg1, arg2,
arg3, arg4, arg5);
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment