Skip to content
GitLab
Menu
Projects
Groups
Snippets
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
Menu
Open sidebar
Gabriel Krisman Bertazi
libcasefold
Commits
a2ffacb0
Commit
a2ffacb0
authored
Mar 08, 2018
by
Gabriel Krisman Bertazi
Browse files
mem_opt
parent
39a7dc69
Changes
3
Hide whitespace changes
Inline
Side-by-side
include/casefold.h
View file @
a2ffacb0
...
...
@@ -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
);
...
...
lib/dcache.c
View file @
a2ffacb0
...
...
@@ -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
.
dirent
s
);
free
(
d
->
sg
.
page
s
);
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
.
dirent
s
[
i
]);
for
(
i
=
0
;
i
<
d
->
sg
.
npage
s
;
i
++
)
free
(
d
->
sg
.
page
s
[
i
]);
if
(
d
->
watcher
)
inotify_destroy_watcher
(
d
->
watcher
);
free
(
d
->
sg
.
dirent
s
);
free
(
d
->
sg
.
page
s
);
free
(
d
->
sg
.
sizes
);
free
(
d
);
...
...
lib/entries.c
View file @
a2ffacb0
...
...
@@ -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
.
npage
s
==
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
);
...
...
Write
Preview
Supports
Markdown
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment